Snap for 6439596 from d34906b95367a971c79c2da4401faad1b9961cca to qt-aml-tzdata-release

Change-Id: If76f5fdf6d1184967b7e12800769090bb47fa826
diff --git a/.bazelrc b/.bazelrc
deleted file mode 100644
index ecd54a5..0000000
--- a/.bazelrc
+++ /dev/null
@@ -1,8 +0,0 @@
-# Include debug info in the compiled jars
-build --javacopt=-g
-build --host_javacopt=-g
-
-# Disable The Guava Beta Checker.
-# TODO(ronshapiro): explore how much work it would be to reenable this
-build --javacopt="-Xep:BetaApi:OFF"
-build --host_javacopt="-Xep:BetaApi:OFF"
diff --git a/.gitignore b/.gitignore
index fabb38f..0c4de1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,35 +1,4 @@
-*~
-\#*\#
-
-.classpath
-.factorypath
-.project
-.settings
-eclipsebin
-
-bin
-gen
-build
-out
-#lib
-
-target
-pom.xml.*
-release.properties
-build.log
-
-.idea
 *.iml
-classes
-
-obj
-
-.DS_Store
-
-dependency-reduced-pom.xml
-
-gen-external-apklibs
-
-/bazel-*
-
-*.pyc
+*.ipr
+*.iws
+.idea
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9015f2e..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-language: android
-
-os: linux
-dist: trusty
-sudo: required
-addons:
-  apt:
-    sources:
-      - ubuntu-toolchain-r-test
-    packages:
-      - libstdc++-4.9-dev # https://github.com/nodegit/nodegit/issues/853
-      - gcc-4.8
-      - g++-4.8
-
-jdk:
-  - &jdk_for_publishing oraclejdk8
-
-android:
-  components:
-    - tools
-    - tools # Duplicated as per https://github.com/travis-ci/travis-ci/issues/6040#issuecomment-219367943
-    - build-tools-26.0.2
-    - android-26
-    - platform-tools
-    - extra-android-m2repository
-
-before_install:
-  - wget https://github.com/bazelbuild/bazel/releases/download/"${BAZEL_VERSION}"/bazel_"${BAZEL_VERSION}"-linux-x86_64.deb
-  - sudo dpkg -i bazel_"${BAZEL_VERSION}"-linux-x86_64.deb
-  - sudo rm -f /etc/mavenrc
-  - wget http://www.us.apache.org/dist/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz
-  - tar -zxf apache-maven-3.1.1-bin.tar.gz
-  - export PATH="$PWD/apache-maven-3.1.1/bin:$PATH"
-  - mkdir travis_bin
-  - ln -s $(which gcc-4.8) travis_bin/gcc
-  - ln -s $(which g++-4.8) travis_bin/g++
-  - export PATH="${PWD}/travis_bin:${PATH}"
-
-script:
-  - bazel test --test_output errors //...
-  - pushd examples && mvn compile && popd
-
-env:
-  global:
-    # Encrypted credentials for deploying snapshots.
-    - secure: eGc3LHBRIPmTnXLM1YoIqG1do9BkpFI2pJm3fz5Cd8UaXtf7Oefa+Ts3rcn4ipee5A+lf8kEouPshSoaQs81KZ2/qf8rSTCIqeFjHR8hzmOVYo/0zRfS/VSUT0yqN+jeRhuNk3+A49RTPlcfJqPv3tyddtrM1vF7axhCJPQIRJM=
-    - secure: LTzrlqcSNeZTOV52D3ibY9RBdxY4Yu8dUOYhAonrWLE+eDTzuoyCzcPw8pEcYVNUi1rG6Q7v3QBDTnBztsPoCbcN5tEGjw5cQEbfEzSTkWaNCFjncWn36cLwx9lgbF+5Db/L0mYJ36unDKUpKVC8AgOtxQibfv/ffugfxxj8ohY=
-
-    # Encrypted GitHub access token to allow util/generate-latest-docs.sh to
-    # push Javadoc to gh-pages.
-    # This uses an access token created by cgdecker and will need to be updated
-    # (see util/generate-latest-docs.sh for a link) if he no longer has
-    # permission to push to the repo.
-    - secure: "UpTUhCQzAGbr5JetRg2GZxp/dPDep/7Il3yGeyDECopciWdx41OPk/QNqAXBhNtKuEaMVsmASyoteuhgaTryQdV4qUIGVOMhES6kbOlYy3nwK44VdsNeeepwVospyDyZbxMtXq5LuHWuTADmAl1mdjNPNoziXc523zjnUzUx/EQ="
-    - JDK_FOR_PUBLISHING: *jdk_for_publishing
-    - BAZEL_VERSION="0.24.1"
-
-after_success:
-  - util/generate-latest-docs.sh
-  - util/publish-snapshot-on-commit.sh
-
-branches:
-  only:
-    - master
-    - /^release.*$/
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index f4a0fdd..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,8 +0,0 @@
-# This is the list of Dagger authors for copyright purposes.
-#
-# This does not necessarily list everyone who has contributed code, since in
-# some cases, their employer may be the copyright holder.  To see the full list
-# of contributors, see the revision history in source control.
-Google Inc.
-Square Inc.
-and other contributors
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 27a05c5..f8e59ef 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,12 +14,12 @@
 
 java_import_host {
     name: "dagger2-auto-common",
-    jars: ["lib/auto-common-0.10.jar"],
+    jars: ["lib/auto-common-1.0-20151022.071545-39.jar"],
 }
 
 java_import_host {
     name: "dagger2-auto-factory-jar",
-    jars: ["lib/auto-factory-1.0-beta6.jar"],
+    jars: ["lib/auto-factory-1.0-20150915.183854-35.jar"],
 }
 
 java_plugin {
@@ -29,19 +29,12 @@
         "dagger2-auto-factory-jar",
         "dagger2-auto-common",
         "guava",
-        "javapoet",
-        "dagger2-google-java-format",
     ],
 }
 
 java_import_host {
     name: "dagger2-auto-service-jar",
-    jars: ["lib/auto-service-1.0-rc5.jar"],
-}
-
-java_import_host {
-    name: "dagger2-auto-service-annotations",
-    jars: ["lib/auto-service-annotations-1.0-rc5.jar"],
+    jars: ["lib/auto-service-1.0-rc2.jar"],
 }
 
 java_plugin {
@@ -50,28 +43,19 @@
     static_libs: [
         "dagger2-auto-common",
         "dagger2-auto-service-jar",
-        "dagger2-auto-service-annotations",
         "guava",
     ],
 }
 
 java_import_host {
     name: "dagger2-auto-value-jar",
-    jars: ["lib/auto-value-1.6.5.jar"],
-}
-
-java_import_host {
-    name: "dagger2-auto-value-annotations",
-    jars: ["lib/auto-value-annotations-1.6.5.jar"],
+    jars: ["lib/auto-value-1.4.1.jar"],
 }
 
 java_plugin {
     name: "dagger2-auto-value",
     processor_class: "com.google.auto.value.processor.AutoValueProcessor",
-    static_libs: [
-        "dagger2-auto-value-jar",
-        "dagger2-auto-value-annotations",
-    ],
+    static_libs: ["dagger2-auto-value-jar"],
 }
 
 java_plugin {
@@ -82,64 +66,42 @@
 
 java_import_host {
     name: "dagger2-google-java-format",
-    jars: ["lib/google-java-format-1.7-all-deps.jar"],
+    jars: ["lib/google-java-format-0.1-20151017.042846-2.jar"],
 }
 
 java_import_host {
     name: "dagger2-inject",
-    jars: ["lib/javax.inject-1.jar"],
-}
-
-java_import_host {
-    name: "dagger2-bootstrap-compiler-jar",
-    jars: ["java/dagger/internal/codegen/bootstrap_compiler_deploy.jar"],
-}
-
-java_plugin {
-    name: "dagger2-bootstrap-compiler",
-    processor_class: "dagger.internal.codegen.ComponentProcessor",
-    generates_api: true,
-    static_libs: ["dagger2-bootstrap-compiler-jar"],
+    jars: ["lib/javax-inject.jar"],
 }
 
 java_library_host {
     name: "dagger2",
 
-    srcs: [
-        "java/dagger/*.java",
-        "java/dagger/internal/*.java",
-        "java/dagger/multibindings/*.java",
-        "java/dagger/releasablereferences/*.java",
-    ],
-    exclude_srcs: ["java/dagger/android/**/*.java"],
+    srcs: ["core/src/main/java/**/*.java"],
 
     static_libs: ["dagger2-inject"],
 
     libs: ["guava"],
 
-    java_version: "1.8",
+    java_version: "1.7",
 }
 
-// build dagger2 producers library
+// build dagger2 producers plugin
 // ============================================================
 
-java_library_host {
+java_plugin {
     name: "dagger2-producers",
 
-    srcs: ["java/dagger/producers/**/*.java"],
+    srcs: ["producers/src/main/java/**/*.java"],
 
-    static_libs: [
-        "dagger2-inject",
-        "error_prone_annotations",
-    ],
+    static_libs: ["dagger2-inject"],
 
     libs: [
         "dagger2",
-        "dagger2-android-annotation-stubs",
         "guava",
     ],
 
-    java_version: "1.8",
+    java_version: "1.7",
 }
 
 // build dagger2 compiler plugin
@@ -149,20 +111,10 @@
     name: "dagger2-compiler",
     processor_class: "dagger.internal.codegen.ComponentProcessor",
     generates_api: true,
-    use_tools_jar: true,
 
-    srcs: [
-        "java/dagger/internal/codegen/**/*.java",
-        "java/dagger/internal/codegen/**/*.proto",
-
-        "java/dagger/model/*.java",
-        "java/dagger/spi/*.java",
-    ],
-
-    exclude_srcs: [
-        "java/dagger/internal/codegen/BindingGraphStatisticsCollector.java",
-        "java/dagger/internal/codegen/DaggerKythePlugin.java",
-    ],
+    // Required for use of javax.annotation.Generated per http://b/62050818
+    javacflags: ["-J--add-modules=java.xml.ws.annotation"],
+    srcs: ["compiler/src/main/java/**/*.java"],
 
     // Manually include META-INF/services/javax.annotation.processing.Processor
     // as the AutoService processor doesn't work properly.
@@ -178,14 +130,6 @@
         "dagger2-inject",
         "dagger2-producers",
         "guava",
-        "javapoet",
-    ],
-
-    // shade guava to avoid conflicts with guava embedded in Error Prone.
-    jarjar_rules: "jarjar-rules.txt",
-
-    libs: [
-        "dagger2-android-annotation-stubs",
     ],
 
     plugins: [
@@ -193,22 +137,7 @@
         "dagger2-auto-service",
         "dagger2-auto-value",
         "dagger2-auto-annotation",
-        "dagger2-bootstrap-compiler",
     ],
 
-    proto: {
-        type: "full",
-        include_dirs: ["external/protobuf/src/"],
-    },
-
-    java_version: "1.8",
-}
-
-// Compile  dummy implementations of annotations used by dagger2 but not
-// present in the Android tree.
-java_library {
-    name: "dagger2-android-annotation-stubs",
-    host_supported: true,
-    sdk_version: "core_current",
-    srcs: ["android-annotation-stubs/src/**/*.java"],
+    java_version: "1.7",
 }
diff --git a/BUILD b/BUILD
deleted file mode 100644
index 8becb3e..0000000
--- a/BUILD
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright (C) 2017 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(default_visibility = ["//visibility:public"])
-
-package_group(
-    name = "src",
-    packages = ["//..."],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-java_library(
-    name = "dagger_with_compiler",
-    exported_plugins = ["//java/dagger/internal/codegen:component-codegen"],
-    exports = ["//java/dagger:core"],
-)
-
-java_library(
-    name = "producers_with_compiler",
-    exports = [
-        ":dagger_with_compiler",
-        "//java/dagger/producers",
-    ],
-)
-
-android_library(
-    name = "android",
-    exported_plugins = ["//java/dagger/android/processor:plugin"],
-    exports = ["//java/dagger/android"],
-)
-
-android_library(
-    name = "android-support",
-    exports = [
-        ":android",
-        "//java/dagger/android/support",
-    ],
-)
-
-load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library")
-
-SHADE_RULES = ["rule com.google.auto.common.** dagger.shaded.auto.common.@1"]
-
-jarjar_library(
-    name = "shaded_compiler",
-    jars = [
-        "//java/dagger/internal/codegen:base",
-        "//java/dagger/internal/codegen:binding",
-        "//java/dagger/internal/codegen:binding_graph_validation",
-        "//java/dagger/internal/codegen:jdk-and-guava-extras",
-        "//java/dagger/internal/codegen:processor",
-        "//java/dagger/internal/codegen:validation",
-        "//java/dagger/internal/codegen:writing",
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/internal/codegen/serialization",
-        "//java/dagger/model:internal-proxies",
-        "//java/dagger/errorprone",
-        "@com_google_auto_auto_common//jar",
-    ],
-    rules = SHADE_RULES,
-)
-
-jarjar_library(
-    name = "shaded_compiler_src",
-    jars = [
-        "//java/dagger/internal/codegen:libbase-src.jar",
-        "//java/dagger/internal/codegen:libbinding-src.jar",
-        "//java/dagger/internal/codegen:libbinding_graph_validation-src.jar",
-        "//java/dagger/internal/codegen:libjdk-and-guava-extras-src.jar",
-        "//java/dagger/internal/codegen:libprocessor-src.jar",
-        "//java/dagger/internal/codegen:libvalidation-src.jar",
-        "//java/dagger/internal/codegen:libwriting-src.jar",
-        "//java/dagger/internal/codegen/javapoet:libjavapoet-src.jar",
-        "//java/dagger/internal/codegen/langmodel:liblangmodel-src.jar",
-        # TODO(ronshapiro): is there a generated src.jar for protos in Bazel?
-        "//java/dagger/errorprone:liberrorprone-src.jar",
-    ],
-)
-
-jarjar_library(
-    name = "shaded_spi",
-    jars = [
-        "//java/dagger/internal/codegen:jdk-and-guava-extras",
-        "//java/dagger/model",
-        "//java/dagger/spi",
-        "@com_google_auto_auto_common//jar",
-    ],
-    rules = SHADE_RULES,
-)
-
-jarjar_library(
-    name = "shaded_spi_src",
-    jars = [
-        "//java/dagger/internal/codegen:libjdk-and-guava-extras-src.jar",
-        "//java/dagger/model:libmodel-src.jar",
-        "//java/dagger/spi:libspi-src.jar",
-    ],
-)
-
-javadoc_library(
-    name = "spi-javadoc",
-    srcs = [
-        "//java/dagger/model:model-srcs",
-        "//java/dagger/spi:spi-srcs",
-    ],
-    root_packages = [
-        "dagger.model",
-        "dagger.spi",
-    ],
-    deps = [
-        "//java/dagger/model",
-        "//java/dagger/spi",
-    ],
-)
-
-jarjar_library(
-    name = "shaded_android_processor",
-    jars = [
-        "//java/dagger/android/processor",
-        "@com_google_auto_auto_common//jar",
-    ],
-    rules = SHADE_RULES,
-)
-
-jarjar_library(
-    name = "shaded_grpc_server_processor",
-    jars = [
-        "//java/dagger/grpc/server/processor",
-        "@com_google_auto_auto_common//jar",
-    ],
-    rules = SHADE_RULES,
-)
-
-# coalesced javadocs used for the gh-pages site
-javadoc_library(
-    name = "user-docs",
-    srcs = [
-        "//java/dagger:javadoc-srcs",
-        "//java/dagger/android:android-srcs",
-        "//java/dagger/android/support:support-srcs",
-        "//java/dagger/grpc/server:javadoc-srcs",
-        "//java/dagger/grpc/server/processor:javadoc-srcs",
-        "//java/dagger/model:model-srcs",
-        "//java/dagger/producers:producers-srcs",
-        "//java/dagger/spi:spi-srcs",
-    ],
-    android_api_level = 26,
-    # TODO(ronshapiro): figure out how to specify the version number for release builds
-    doctitle = "Dagger Dependency Injection API",
-    exclude_packages = [
-        "dagger.internal",
-        "dagger.producers.internal",
-        "dagger.producers.monitoring.internal",
-    ],
-    root_packages = ["dagger"],
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/android",
-        "//java/dagger/android/support",
-        "//java/dagger/grpc/server",
-        "//java/dagger/grpc/server/processor",
-        "//java/dagger/model",
-        "//java/dagger/producers",
-        "//java/dagger/spi",
-    ],
-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 09c4282..3a38bfc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,87 @@
 Change Log
 ==========
 
--   For Dagger 2 releases, please see https://github.com/google/dagger/releases
--   For Dagger 1 (`ObjectGraph`) releases, see
-    https://github.com/square/dagger/blob/master/CHANGELOG.md
+Dagger 2 (Components)
+---------------------
+
+### Version 2.0.2 *(2015-11-03)*
+
+A patch release, most crucially including:
+
+  * A fix to the way processor validation of types is done that permits dagger to play
+    more nicely with other processors, avoiding over-validating aspects that it doesn't
+    need, which may yet not have been generated by other processors in a different round
+    of processing.
+  * Some improved error reporting for edge-cases
+  * Fix to prevent incompatible versions of Guava on the classpath from blowing up processing
+  * Support a more robust set of types for map keys in map bindings (primitive types, etc.)
+
+### Version 2.0.1 *(2015-05-28)*
+
+A maintenance release fixing immediate issues following the Dagger 2.0 release, including:
+
+  * Speed up Graph Validation (reduce build times by 10s of seconds on sampled large projects)
+  * Generate correct code for @MapKey annotation types (beta)
+  * Fix to properly emit code for class literal values in @MapKey annotations.
+  * Fix for injecting component dependencies
+  * Fixes to generated code to account for differences in generics handling in ecg vs. javac.
+  * Subcomponents can now be abstract classes.
+  * Subcomponents now properly build the object graph in some cases involving explicit bindings
+    and (sub)components without scope.
+  * Improve runtime performance of SetFactory (set multibindings)
+  * Other smaller fixes, refactorings, etc.
+
+### Version 2.0.0 *(2015-04-21)*
+
+The initial release of the 2.0 code-line, supporting:
+
+  * `@Component` interfaces representing a custom API to access a graph of objects
+  * JSR-330 injection automation using `@Inject` signals, `@Qualifiers`
+  * Simple bindings of implementations to interfaces, custom provision of objects, and set-bindings
+  * Compile-time validation of graph structure (cycles, missing bindings, duplicate bindings)
+  * Generation of 
+    - backing implementations for components
+    - factories for `@Inject` constructors and modules
+    - members-injectors for `@Inject` methods and fields
+  * Beta support for
+    - Map bindings
+    - [Producers](http://google.github.io/dagger/api/latest/dagger/producers/Producer.html)
+
+==============================================================
+
+Dagger 1 (ObjectGraph)
+----------------------
+
+### Version 1.2.0 *(2013-12-13)*
+
+ * Numerous performance improvements in both the compiler and runtime.
+   * Use more efficient `String` concatenation.
+   * Module adapters are now stateless.
+   * Use read/write locks over global locks.
+   * Reflective constructor invocation is now cached with `Class.newInstance`.
+   * Avoid re-linking all bindings when calling `.plus()`.
+ * Set bindings are now unioned when calling `.plus()`.
+ * Fix: Tolerate missing type information during compilation by deferring writing
+   module adapters.
+
+
+### Version 1.1.0 *(2013-08-05)*
+
+ * Module loading now requires code generation via the 'dagger-compiler' artifact.
+ * Allow multiple contributions to Set binding via `Provides.Type.SET_VALUES`.
+ * Request classloading from the classloader of the requesting object, not the current thread's
+   context classloader.
+ * Cache class loading at the root injector to reduce costs of loading adapters.
+ * Fix: Primitive array types are no longer incorrectly changed to their boxed type.
+ * Update JavaWriter to 2.1.1.
+
+
+### Version 1.0.1 *(2013-06-03)*
+
+ * Explicitly forbid declaring `@Inject` on a class type (e.g., `@Inject class Foo {}`).
+ * Update JavaWriter to 1.0.5.
+
+
+### Version 1.0.0 *(2013-05-07)*
+
+Initial release.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 45f15c4..087af22 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,69 +1,37 @@
-# How to contribute
+Contributing
+============
 
-We'd love to accept your patches and contributions to this project. There are
-just a few small guidelines you need to follow.
+If you would like to contribute code to Dagger you can do so through GitHub by
+forking the repository and sending a pull request.
 
-## Contributor License Agreement
+When submitting code, please make every effort to follow existing conventions
+and style in order to keep the code as readable as possible.  
 
-Contributions to any Google project must be accompanied by a Contributor License
-Agreement. This is necessary because you own the copyright to your changes, even
-after your contribution becomes part of this project. So this agreement simply
-gives us permission to use and redistribute your contributions as part of the
-project. Head over to <https://cla.developers.google.com/> to see your current
-agreements on file or to sign a new one.
+Where appropriate, please provide unit tests or integration tests. Unit tests
+should be JUnit based tests and can use either standard JUnit assertions or
+FEST assertions and be added to `<project>/src/test/java`.  Changes to build-time
+behaviour (such as changes to code generation or graph validation) should go into
+small maven projects using the `maven-invoker-plugin`.  Examples of this are in
+`core/src/it` and can include bean-shell verification scripts and other
+facilities provided by `maven-invoker-plugin`.
 
-You generally only need to submit a CLA once, so if you've already submitted one
-(even if it was for a different project), you probably don't need to do it
-again.
+Please make sure your code compiles by running `mvn clean verify` which will
+execute both unit and integration test phases.  Additionally, consider using 
+http://travis-ci.org to validate your branches before you even put them into
+pull requests.  All pull requests will be validated by Travis-ci in any case
+and must pass before being merged.
 
-## Code reviews
+If you are adding or modifying files you may add your own copyright line, but
+please ensure that the form is consistent with the existing files, and please
+note that a Square, Inc. copyright line must appear in every copyright notice.
+All files are released with the Apache 2.0 license.
 
-All submissions, including submissions by project members, require review. We
-use GitHub pull requests for this purpose. Consult [GitHub Help] for more
-information on using pull requests.
+Checkstyle failures during compilation indicate errors in your style and will
+be displayed in the console output of the build (including in Travis-CI output),
+or can be viewed in the `checkstyle-result.xml` file.
 
-[GitHub Help]: https://help.github.com/articles/about-pull-requests/
+Before your code can be accepted into the project you must sign the
+[Individual Contributor License Agreement (CLA)][1].
 
-## Building Dagger
 
-Dagger is built with [`bazel`](https://bazel.build).
-
-### Building Dagger from the command line
-
-*   [Install Bazel](https://docs.bazel.build/versions/master/install.html)
-*   Build the Dagger project with `bazel build <target>`
-    *   Learn more about Bazel targets [here][bazel targets].
-    *   If you see an error similar to `ERROR: missing input file
-        '@androidsdk//:build-tools/26.0.2/aapt'`, install the missing build
-        tools version with the android `sdkmanager` tool.
-*   Run tests with `bazel test <target>`, or `bazel test //...` to run all
-    tests
-*   You can install the Dagger libraries in your **local maven repository** by
-    running the `./util/install-local-snapshot.sh` script.
-    *   It will build the libraries and install them with a `LOCAL-SNAPSHOT`
-        version.
-
-[bazel targets]: https://docs.bazel.build/versions/master/build-ref.html
-
-### Importing the Dagger project in IntelliJ/Android Studio
-
-*   Visit `Preferences > Plugins` in the IDE menu.
-    *   Search for `bazel` and install the plugin.
-    *   If no result shows up, click on `Search in repositories`, search for
-        `bazel` and install the plugin.
-*   Select `Import Bazel Project`.
-*   Input the path to the Dagger project under `workspace`, click `Next`.
-*   Select `Generate from BUILD file`, type `BUILD` in the `Build file` input,
-    click `Next`.
-*   [Android Studio only] In the `Project View` form, uncomment one of the
-    `android_sdk_platform` lines. Pick one that you have installed, then click
-    `Finish`.
-*   If you get an error on Bazel sync, `Cannot run program "bazel"`, then:
-    *   In the command line, run `where bazel` and copy the output  (e.g.
-        `/usr/local/bin/bazel`)
-    *   In Android Studio, go to `Preferences > Bazel Settings` and replace
-        `Bazel binary location` with what you just copied.
-*   Note that the first sync can take a long time. When build files are changed,
-    you can run partial syncs (which should be faster) from the file menu.
-*   [Android Studio only] To view the Dagger project structure, open the
-    `Project` view and switch the top selector from `Android` to `Project`.
+ [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
diff --git a/METADATA b/METADATA
deleted file mode 100644
index 59b9e25..0000000
--- a/METADATA
+++ /dev/null
@@ -1,17 +0,0 @@
-name: "dagger2"
-description:
-    "A fast dependency injector for Android and Java."
-
-third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://dagger.dev"
-  }
-  url {
-    type: GIT
-    value: "https://github.com/google/dagger"
-  }
-  version: "dagger-2.23.1"
-  last_upgrade_date { year: 2019 month: 6 day: 14 }
-  license_type: PERMISSIVE
-}
diff --git a/OWNERS b/OWNERS
index 87a5dbe..22cc91a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1,2 @@
-include platform/libcore:/OWNERS
+paulduffin@google.com
+nfuller@google.com
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..1983221
--- /dev/null
+++ b/README.android
@@ -0,0 +1,12 @@
+URL: https://github.com/google/dagger.git
+License: Apache 2
+Description: "Dagger 2 - A fast dependency injector for Android and Java"
+
+Version: 91f7d8bda5b1ef2fdf768758c88d3e5f069210ea
+
+Upstream depends (slightly) on Guava v19 but we only have Guava v18 in
+Android at the moment so we have reverted those changes that introduced
+a dependency on Guava v19.
+
+Local Patches:
+    Revert "Stop using deprecated Futures method." - upstream 0a2ca81c0f78c621968deb58f4b42117db43fec4
diff --git a/README.md b/README.md
index a9ebc26..3c0e8bc 100644
--- a/README.md
+++ b/README.md
@@ -1,204 +1,110 @@
-# Dagger 2
-
-[![Maven Central][mavenbadge-svg]][mavencentral]
+Dagger 2
+========
 
 A fast dependency injector for Android and Java.
 
-## About Google's Fork
+About Google's Fork
+-------------
 
-Dagger 2 is a compile-time evolution approach to dependency injection.
-Taking the approach started in Dagger 1.x to its ultimate conclusion,
-Dagger 2.x eliminates all reflection, and improves code clarity by
-removing the traditional ObjectGraph/Injector in favor of user-specified
-`@Component` interfaces.
+Dagger 2 is a compile-time evolution approach to dependency injection.  Taking the approach
+started in Dagger 1.x to its ultimate conclusion, Dagger 2.0 eliminates all reflection, and
+improves code clarity by removing the traditional ObjectGraph/Injector in favor of
+user-specified @Component interfaces. 
 
-This github project represents the Dagger 2 development stream.  The earlier
-[project page][square] (Square, Inc's repository) represents the earlier 1.0
-development stream. Both versions have benefited from strong involvement from
-Square, Google, and other contributors.
+This github project represents the Dagger 2 development stream.  The earlier 
+[project page][square] (Square, Inc's repository) represents the earlier 1.0 development stream.  
+Both versions have benefitted from strong involvement from Square, Google, and other contributors. 
 
-Dagger is currently in active development, primarily internally at Google,
-with regular pushes to the open-source community. Snapshot releases are
-auto-deployed to sonatype's central maven repository on every clean build with
-the version `HEAD-SNAPSHOT`.
+## [Dagger 2's main documentation website can be found here.][website]
 
-> [Dagger 2's main documentation website can be found here.][website]
+Status
+------
 
-## Documentation
+  - ***Release Version:* 2.0.1**
+  - ***Snapshot Version:* 2.1-SNAPSHOT**
+
+Dagger is currently in active development, primarily internally at Google, with regular pushes
+to the open-source community.  Snapshot releases are auto-deployed to sonatype's central maven
+repository on a clean build with the version `2.1-SNAPSHOT`.
+
+Documentation
+-------------
 
 You can [find the dagger documentation here][website] which has extended usage
 instructions and other useful information.  Substantial usage information can be
 found in the [API documentation][20api].
 
-You can also learn more from [the original proposal][proposal],
+You can also learn more from [the original proposal][proposal], 
 [this talk by Greg Kick][gaktalk], and on the dagger-discuss@googlegroups.com
-mailing list.
+mailing list. 
 
-## Installation
+Installation
+--------
 
-### Bazel
-
-If you build with `bazel`, follow the [`bazel` documentation for referencing
-external projects][bazel-external-deps] to include Dagger in your build.
-
-Given the following `WORKSPACE` definition, you can reference dagger via
-`@com_google_dagger//:dagger_with_compiler` in your deps.
-
-```python
-http_archive(
-    name = "com_google_dagger",
-    urls = ["https://github.com/google/dagger/archive/dagger-<version>.zip"],
-)
-```
-
-### Other build systems
-
-You will need to include the `dagger-2.x.jar` in your application's runtime.
+You will need to include the `dagger-2.0.1.jar` in your application's runtime.
 In order to activate code generation and generate implementations to manage
-your graph you will need to include `dagger-compiler-2.x.jar` in your build
+your graph you will need to include `dagger-compiler-2.0.1.jar` in your build
 at compile time.
 
-#### Maven
-
 In a Maven project, include the `dagger` artifact in the dependencies section
-of your `pom.xml` and the `dagger-compiler` artifact as an
-`annotationProcessorPaths` value of the `maven-compiler-plugin`:
+of your `pom.xml` and the `dagger-compiler` artifact as either an `optional` or
+`provided` dependency:
 
 ```xml
 <dependencies>
   <dependency>
     <groupId>com.google.dagger</groupId>
     <artifactId>dagger</artifactId>
-    <version>2.x</version>
-  </dependency>
-</dependencies>
-<build>
-  <plugins>
-    <plugin>
-      <groupId>org.apache.maven.plugins</groupId>
-      <artifactId>maven-compiler-plugin</artifactId>
-      <version>3.6.1</version>
-      <configuration>
-        <annotationProcessorPaths>
-          <path>
-            <groupId>com.google.dagger</groupId>
-            <artifactId>dagger-compiler</artifactId>
-            <version>2.x</version>
-          </path>
-        </annotationProcessorPaths>
-      </configuration>
-    </plugin>
-  </plugins>
-</build>
-```
-
-If you are using a version of the `maven-compiler-plugin` lower than `3.5`, add
-the `dagger-compiler` artifact with the `provided` scope:
-
-```xml
-<dependencies>
-  <dependency>
-    <groupId>com.google.dagger</groupId>
-    <artifactId>dagger</artifactId>
-    <version>2.x</version>
+    <version>2.0.1</version>
   </dependency>
   <dependency>
     <groupId>com.google.dagger</groupId>
     <artifactId>dagger-compiler</artifactId>
-    <version>2.x</version>
-    <scope>provided</scope>
+    <version>2.0.1</version>
+    <optional>true</optional>
   </dependency>
 </dependencies>
 ```
 
-If you use the beta `dagger-producers` extension (which supplies
-parallelizable execution graphs), then add this to your maven configuration:
+If you use the beta `dagger-producers` extension (which supplies parallelizable execution graphs),
+then add this to your maven configuration:
 
 ```xml
 <dependencies>
   <dependency>
     <groupId>com.google.dagger</groupId>
     <artifactId>dagger-producers</artifactId>
-    <version>2.x</version>
+    <version>2.0-beta</version>
   </dependency>
 </dependencies>
 ```
 
-#### Java Gradle
-```groovy
-// Add plugin https://plugins.gradle.org/plugin/net.ltgt.apt
-plugins {
-  id "net.ltgt.apt" version "0.10"
-}
 
-// Add Dagger dependencies
-dependencies {
-  compile 'com.google.dagger:dagger:2.x'
-  apt 'com.google.dagger:dagger-compiler:2.x'
-}
-```
-
-#### Android Gradle
-```groovy
-// Add Dagger dependencies
-dependencies {
-  compile 'com.google.dagger:dagger:2.x'
-  annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
-}
-```
-
-If you're using classes in `dagger.android` you'll also want to include:
-
-```groovy
-compile 'com.google.dagger:dagger-android:2.x'
-compile 'com.google.dagger:dagger-android-support:2.x' // if you use the support libraries
-annotationProcessor 'com.google.dagger:dagger-android-processor:2.x'
-```
-
-If you're using a version of the Android gradle plugin below `2.2`, see
-https://bitbucket.org/hvisser/android-apt.
-
-If you're using the [Android Databinding library][databinding], you may want to
-increase the number of errors that `javac` will print. When Dagger prints an
-error, databinding compilation will halt and sometimes print more than 100
-errors, which is the default amount for `javac`. For more information, see
-[Issue 306](https://github.com/google/dagger/issues/306).
-
-```groovy
-gradle.projectsEvaluated {
-  tasks.withType(JavaCompile) {
-    options.compilerArgs << "-Xmaxerrs" << "500" // or whatever number you want
-  }
-}
-```
-
-### Download
+### Download 
 
   * 2.x (google/dagger)
     * [Dagger 2.0 Documentation][website]
     * [Dagger 2.0 Javadocs][20api]
-    * [Dagger development Javadocs][latestapi] (from the `master` branch
-      on GitHub)
+    * [Dagger development Javadocs][latestapi] (from the `master` branch on GitHub)
     * [Google's Dagger project site on GitHub][project]
+    * <a href="https://plus.google.com/118328287768685565185" rel="publisher">Google+ Dagger Project Page</a>
+    * [Google+ Dagger Users Community][community]
   * 1.x (square/dagger)
     * [Square's original Dagger project site on GitHub][square]
+    * [Square Open Source Community][squarecommunity]
 
 
-If you do not use maven, gradle, ivy, or other build systems that consume
-maven-style binary artifacts, they can be downloaded directly via the
-[Maven Central Repository][mavencentral].
+If you do not use maven, gradle, ivy, or other build systems that consume maven-style binary
+artifacts, they can be downloaded directly via the [Maven Central Repository][mavensearch].
 
-Developer snapshots are available from Sonatype's
-[snapshot repository][dagger-snap], and are built on a clean build of
-the GitHub project's master branch.
+Developer snapshots are available from [Sonatype's snapshot repository][dagger-snap], and
+are built on a clean build of the GitHub project's master branch.
 
-## Building Dagger
+License
+-------
 
-See [the CONTRIBUTING.md docs][Building Dagger].
-
-## License
-
-    Copyright 2012 The Dagger Authors
+    Copyright 2012 Square, Inc.
+    Copyright 2012 Google, Inc.
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -212,17 +118,17 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-[20api]: https://dagger.dev/api/2.0/
-[`bazel`]: https://bazel.build
-[bazel-external-deps]: https://docs.bazel.build/versions/master/external.html#depending-on-other-bazel-projects
-[Building Dagger]: CONTRIBUTING.md#building-dagger
-[dagger-snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/dagger/
-[databinding]: https://developer.android.com/topic/libraries/data-binding/
-[gaktalk]: https://www.youtube.com/watch?v=oK_XtfXPkqw
-[latestapi]: https://dagger.dev/api/latest/
-[mavenbadge-svg]: https://maven-badges.herokuapp.com/maven-central/com.google.dagger/dagger/badge.svg
-[mavencentral]: https://search.maven.org/artifact/com.google.dagger/dagger
-[project]: http://github.com/google/dagger/
-[proposal]: https://github.com/square/dagger/issues/366
-[square]: http://github.com/square/dagger/
-[website]: https://dagger.dev
+
+
+ [mavensearch]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.google.dagger%22
+ [dagger-snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/dagger/
+ [website]: http://google.github.io/dagger
+ [latestapi]: http://google.github.io/dagger/api/latest/
+ [20api]: http://google.github.io/dagger/api/2.0/
+ [gaktalk]: https://www.youtube.com/watch?v=oK_XtfXPkqw
+ [proposal]: https://github.com/square/dagger/issues/366
+ [project]: http://github.com/google/dagger/
+ [community]: https://plus.google.com/communities/111933036769103367883
+ [square]: http://github.com/square/dagger/
+ [squarecommunity]: https://plus.google.com/communities/109244258569782858265
+
diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644
index 8758b38..0000000
--- a/WORKSPACE
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2017 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.
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-http_archive(
-    name = "google_bazel_common",
-    strip_prefix = "bazel-common-26011657fee96a949c66500b1662c4c7288a4968",
-    urls = ["https://github.com/google/bazel-common/archive/26011657fee96a949c66500b1662c4c7288a4968.zip"],
-)
-
-load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules")
-
-google_common_workspace_rules()
-
-# This fixes an issue with protobuf starting to use zlib by default in 3.7.0.
-# TODO(ronshapiro): Figure out if this is in fact necessary, or if proto can depend on the
-# @bazel_tools library directly. See discussion in
-# https://github.com/protocolbuffers/protobuf/pull/5389#issuecomment-481785716
-bind(
-    name = "zlib",
-    actual = "@bazel_tools//third_party/zlib",
-)
diff --git a/android-annotation-stubs/gen_annotations.sh b/android-annotation-stubs/gen_annotations.sh
deleted file mode 100755
index 21aeb46..0000000
--- a/android-annotation-stubs/gen_annotations.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-
-declare -A INNER
-declare -A PARAMETER
-declare -A IMPORT
-
-ANNOTATIONS=(
-    org.checkerframework.checker.nullness.compatqual.NullableDecl
-    net.ltgt.gradle.incap.IncrementalAnnotationProcessor
-)
-
-PARAMETER["net.ltgt.gradle.incap.IncrementalAnnotationProcessor"]="IncrementalAnnotationProcessorType"
-IMPORT["net.ltgt.gradle.incap.IncrementalAnnotationProcessor"]="net.ltgt.gradle.incap.IncrementalAnnotationProcessorType"
-
-for a in ${ANNOTATIONS[@]}; do
-    package=${a%.*}
-    class=${a##*.}
-    dir=$(dirname $0)/src/${package//.//}
-    file=${class}.java
-    inner=${INNER[$a]}
-    parameter=${PARAMETER[$a]}
-    import=
-
-    if [ -n "${parameter}" ]; then
-	parameter="${parameter} value();"
-    fi
-
-    for i in ${IMPORT[$a]}; do
-	import="${import}import ${i};"
-    done
-
-    mkdir -p ${dir}
-    sed -e"s/__PACKAGE__/${package}/" \
-	-e"s/__CLASS__/${class}/" \
-	-e"s/__INNER__/${inner}/" \
-	-e"s/__PARAMETER__/${parameter}/" \
-	-e"s/__IMPORT__/${import}/" \
-	$(dirname $0)/tmpl.java > ${dir}/${file}
-    google-java-format -i ${dir}/${file}
-done
-
-f=$(dirname $0)/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessorType.java
-cat > ${f} <<EOF
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 net.ltgt.gradle.incap;
-public enum IncrementalAnnotationProcessorType {
-  DYNAMIC
-}
-EOF
diff --git a/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessor.java b/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessor.java
deleted file mode 100644
index aa1ce76..0000000
--- a/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 net.ltgt.gradle.incap;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/* This is an annotation stub to avoid dependencies on annotations that aren't
- * in the Android platform source tree. */
-
-@Target({
-  ElementType.ANNOTATION_TYPE,
-  ElementType.CONSTRUCTOR,
-  ElementType.FIELD,
-  ElementType.LOCAL_VARIABLE,
-  ElementType.METHOD,
-  ElementType.PACKAGE,
-  ElementType.PARAMETER,
-  ElementType.TYPE,
-  ElementType.TYPE_PARAMETER,
-  ElementType.TYPE_USE
-})
-@Retention(RetentionPolicy.SOURCE)
-public @interface IncrementalAnnotationProcessor {
-
-  IncrementalAnnotationProcessorType value();
-}
diff --git a/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessorType.java b/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessorType.java
deleted file mode 100644
index 83e3590..0000000
--- a/android-annotation-stubs/src/net/ltgt/gradle/incap/IncrementalAnnotationProcessorType.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 net.ltgt.gradle.incap;
-public enum IncrementalAnnotationProcessorType {
-  DYNAMIC
-}
diff --git a/android-annotation-stubs/src/org/checkerframework/checker/nullness/compatqual/NullableDecl.java b/android-annotation-stubs/src/org/checkerframework/checker/nullness/compatqual/NullableDecl.java
deleted file mode 100644
index 2d39b0f..0000000
--- a/android-annotation-stubs/src/org/checkerframework/checker/nullness/compatqual/NullableDecl.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 org.checkerframework.checker.nullness.compatqual;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/* This is an annotation stub to avoid dependencies on annotations that aren't
- * in the Android platform source tree. */
-
-@Target({
-  ElementType.ANNOTATION_TYPE,
-  ElementType.CONSTRUCTOR,
-  ElementType.FIELD,
-  ElementType.LOCAL_VARIABLE,
-  ElementType.METHOD,
-  ElementType.PACKAGE,
-  ElementType.PARAMETER,
-  ElementType.TYPE,
-  ElementType.TYPE_PARAMETER,
-  ElementType.TYPE_USE
-})
-@Retention(RetentionPolicy.SOURCE)
-public @interface NullableDecl {}
diff --git a/android-annotation-stubs/tmpl.java b/android-annotation-stubs/tmpl.java
deleted file mode 100644
index c4df609..0000000
--- a/android-annotation-stubs/tmpl.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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 __PACKAGE__;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-__IMPORT__
-
-/* This is an annotation stub to avoid dependencies on annotations that aren't
- * in the Android platform source tree. */
-
-@Target({
-  ElementType.ANNOTATION_TYPE,
-  ElementType.CONSTRUCTOR,
-  ElementType.FIELD,
-  ElementType.LOCAL_VARIABLE,
-  ElementType.METHOD,
-  ElementType.PACKAGE,
-  ElementType.PARAMETER,
-  ElementType.TYPE,
-  ElementType.TYPE_PARAMETER,
-  ElementType.TYPE_USE})
-@Retention(RetentionPolicy.SOURCE)
-public @interface __CLASS__ {
-  __INNER__
-  __PARAMETER__
-}
diff --git a/build_defs.bzl b/build_defs.bzl
deleted file mode 100644
index 0bd7402..0000000
--- a/build_defs.bzl
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2017 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.
-
-"""This file defines constants useful across the Dagger build."""
-
-DOCLINT_HTML_AND_SYNTAX = ["-Xdoclint:html,syntax"]
-
-DOCLINT_REFERENCES = ["-Xdoclint:reference"]
-
-SOURCE_7_TARGET_7 = [
-    "-source",
-    "1.7",
-    "-target",
-    "1.7",
-]
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..e7ffbc0
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<module name="Checker">
+    <!--module name="NewlineAtEndOfFile"/-->
+    <module name="FileLength"/>
+    <module name="FileTabCharacter"/>
+
+    <!-- Trailing spaces -->
+    <module name="RegexpSingleline">
+        <property name="format" value="\s+$"/>
+        <property name="message" value="Line has trailing spaces."/>
+    </module>
+
+    <!-- Space after 'for' and 'if' -->
+    <module name="RegexpSingleline">
+        <property name="format" value="^\s*(for|if)[^ ]"/>
+        <property name="message" value="Space needed before opening parenthesis."/>
+    </module>
+
+    <!-- For each spacing -->
+    <module name="RegexpSingleline">
+        <property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
+        <property name="message" value="Space needed around ':' character."/>
+    </module>
+
+    <module name="TreeWalker">
+        <property name="cacheFile" value="${checkstyle.cache.file}"/>
+
+        <!-- Checks for Javadoc comments.                     -->
+        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+        <!--module name="JavadocMethod"/-->
+        <!--module name="JavadocType"/-->
+        <!--module name="JavadocVariable"/-->
+        <!--module name="JavadocStyle"/-->
+
+
+        <!-- Checks for Naming Conventions.                  -->
+        <!-- See http://checkstyle.sf.net/config_naming.html -->
+        <!--<module name="ConstantName"/>-->
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+
+
+        <!-- Checks for imports                              -->
+        <!-- See http://checkstyle.sf.net/config_import.html -->
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <module name="RedundantImport"/>
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="true"/>
+        </module>
+
+        <!-- Checks for Size Violations.                    -->
+        <!-- See http://checkstyle.sf.net/config_sizes.html -->
+        <module name="LineLength">
+            <property name="max" value="100"/>
+        </module>
+        <module name="MethodLength">
+            <property name="max" value="200"/>
+        </module>
+        <!--module name="ParameterNumber"/-->
+
+
+        <!-- Checks for whitespace                               -->
+        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+        <module name="GenericWhitespace"/>
+        <module name="EmptyForIteratorPad"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter"/>
+        <module name="NoWhitespaceBefore"/>
+        <module name="OperatorWrap"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="WhitespaceAfter"/>
+        <module name="WhitespaceAround">
+          <property name="allowEmptyConstructors" value="true" />
+          <property name="allowEmptyMethods" value="true" />
+        </module>
+
+
+        <!-- Modifier Checks                                    -->
+        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+        <!--module name="ModifierOrder"/-->
+        <module name="RedundantModifier"/>
+
+
+        <!-- Checks for blocks. You know, those {}'s         -->
+        <!-- See http://checkstyle.sf.net/config_blocks.html -->
+        <!--module name="AvoidNestedBlocks"/-->
+        <!--module name="EmptyBlock"/-->
+        <module name="LeftCurly"/>
+        <!--module name="NeedBraces"/-->
+        <module name="RightCurly"/>
+
+
+        <!-- Checks for common coding problems               -->
+        <!-- See http://checkstyle.sf.net/config_coding.html -->
+        <!--module name="AvoidInlineConditionals"/-->
+        <module name="CovariantEquals"/>
+        <module name="EmptyStatement"/>
+        <!--<module name="EqualsAvoidNull"/>-->
+        <module name="EqualsHashCode"/>
+        <!--module name="HiddenField"/-->
+        <module name="IllegalInstantiation"/>
+        <!--<module name="InnerAssignment"/>-->
+        <!--module name="MagicNumber"/-->
+        <module name="MissingSwitchDefault"/>
+        <module name="RedundantThrows"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+
+        <!-- Checks for class design                         -->
+        <!-- See http://checkstyle.sf.net/config_design.html -->
+        <!--module name="DesignForExtension"/-->
+        <!--module name="FinalClass"/-->
+        <!--module name="HideUtilityClassConstructor"/-->
+        <!--module name="InterfaceIsType"/-->
+        <!--module name="VisibilityModifier"/-->
+
+
+        <!-- Miscellaneous other checks.                   -->
+        <!-- See http://checkstyle.sf.net/config_misc.html -->
+        <!--module name="ArrayTypeStyle"/-->
+        <!--module name="FinalParameters"/-->
+        <!--module name="TodoComment"/-->
+        <module name="UpperEll"/>
+    </module>
+</module>
diff --git a/compiler/dependency-reduced-pom.xml b/compiler/dependency-reduced-pom.xml
new file mode 100644
index 0000000..504f9ff
--- /dev/null
+++ b/compiler/dependency-reduced-pom.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+  <parent>

+    <artifactId>dagger-parent</artifactId>

+    <groupId>com.google.dagger</groupId>

+    <version>2.1-SNAPSHOT</version>

+  </parent>

+  <modelVersion>4.0.0</modelVersion>

+  <artifactId>dagger-compiler</artifactId>

+  <name>Dagger Compiler</name>

+  <description>Tools to generate Dagger injection and module adapters from annotated code and validate them.</description>

+  <build>

+    <plugins>

+      <plugin>

+        <artifactId>maven-compiler-plugin</artifactId>

+        <executions>

+          <execution>

+            <id>default-compile</id>

+            <goals>

+              <goal>compile</goal>

+            </goals>

+            <configuration>

+              <annotationProcessors>

+                <annotationProcessor>com.google.auto.value.processor.AutoValueProcessor</annotationProcessor>

+                <annotationProcessor>com.google.auto.service.processor.AutoServiceProcessor</annotationProcessor>

+              </annotationProcessors>

+            </configuration>

+          </execution>

+          <execution>

+            <id>default-test-compile</id>

+            <goals>

+              <goal>testCompile</goal>

+            </goals>

+            <configuration>

+              <annotationProcessors>

+                <annotationProcessor>dagger.internal.codegen.ComponentProcessor</annotationProcessor>

+              </annotationProcessors>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+      <plugin>

+        <artifactId>maven-invoker-plugin</artifactId>

+        <executions>

+          <execution>

+            <id>integration-test</id>

+            <goals>

+              <goal>install</goal>

+              <goal>run</goal>

+            </goals>

+          </execution>

+        </executions>

+        <configuration>

+          <addTestClassPath>true</addTestClassPath>

+          <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>

+          <cloneClean>true</cloneClean>

+          <profiles>

+            <profile>!sonatype-oss-release</profile>

+          </profiles>

+          <pomIncludes>

+            <pomInclude>*/pom.xml</pomInclude>

+          </pomIncludes>

+          <localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>

+          <filterProperties>

+            <dagger.version>${project.version}</dagger.version>

+            <dagger.groupId>${project.groupId}</dagger.groupId>

+          </filterProperties>

+          <streamLogs>true</streamLogs>

+        </configuration>

+      </plugin>

+      <plugin>

+        <artifactId>maven-shade-plugin</artifactId>

+        <version>2.3</version>

+        <executions>

+          <execution>

+            <phase>package</phase>

+            <goals>

+              <goal>shade</goal>

+            </goals>

+            <configuration>

+              <minimizeJar>true</minimizeJar>

+              <artifactSet>

+                <excludes>

+                  <exclude>com.google.guava</exclude>

+                  <exclude>com.google.auto.service</exclude>

+                  <exclude>com.google.auto.value</exclude>

+                  <exclude>com.google.dagger:dagger</exclude>

+                  <exclude>com.google.dagger:dagger-producers</exclude>

+                  <exclude>javax.inject</exclude>

+                </excludes>

+              </artifactSet>

+              <relocations>

+                <relocation>

+                  <pattern>com.google.auto.common</pattern>

+                  <shadedPattern>dagger.shaded.auto.common</shadedPattern>

+                </relocation>

+              </relocations>

+            </configuration>

+          </execution>

+        </executions>

+      </plugin>

+    </plugins>

+  </build>

+  <dependencies>

+    <dependency>

+      <groupId>com.google.dagger</groupId>

+      <artifactId>dagger</artifactId>

+      <version>2.1-SNAPSHOT</version>

+      <scope>compile</scope>

+    </dependency>

+    <dependency>

+      <groupId>com.google.dagger</groupId>

+      <artifactId>dagger-producers</artifactId>

+      <version>2.1-SNAPSHOT</version>

+      <scope>compile</scope>

+    </dependency>

+    <dependency>

+      <groupId>com.google.auto.service</groupId>

+      <artifactId>auto-service</artifactId>

+      <version>1.0-rc2</version>

+      <scope>compile</scope>

+      <optional>true</optional>

+    </dependency>

+    <dependency>

+      <groupId>com.google.guava</groupId>

+      <artifactId>guava</artifactId>

+      <version>18.0</version>

+      <scope>compile</scope>

+    </dependency>

+    <dependency>

+      <groupId>com.google.auto.value</groupId>

+      <artifactId>auto-value</artifactId>

+      <version>1.0</version>

+      <scope>compile</scope>

+      <optional>true</optional>

+    </dependency>

+    <dependency>

+      <groupId>junit</groupId>

+      <artifactId>junit</artifactId>

+      <version>4.11</version>

+      <scope>test</scope>

+      <exclusions>

+        <exclusion>

+          <artifactId>hamcrest-core</artifactId>

+          <groupId>org.hamcrest</groupId>

+        </exclusion>

+      </exclusions>

+    </dependency>

+    <dependency>

+      <groupId>com.google.dagger</groupId>

+      <artifactId>dagger</artifactId>

+      <version>2.1-SNAPSHOT</version>

+      <classifier>tests</classifier>

+      <scope>test</scope>

+    </dependency>

+    <dependency>

+      <groupId>com.google.testing.compile</groupId>

+      <artifactId>compile-testing</artifactId>

+      <version>0.7</version>

+      <scope>test</scope>

+      <exclusions>

+        <exclusion>

+          <artifactId>tools</artifactId>

+          <groupId>com.sun</groupId>

+        </exclusion>

+      </exclusions>

+    </dependency>

+    <dependency>

+      <groupId>com.google.guava</groupId>

+      <artifactId>guava-testlib</artifactId>

+      <version>18.0</version>

+      <scope>test</scope>

+      <exclusions>

+        <exclusion>

+          <artifactId>jsr305</artifactId>

+          <groupId>com.google.code.findbugs</groupId>

+        </exclusion>

+      </exclusions>

+    </dependency>

+    <dependency>

+      <groupId>org.mockito</groupId>

+      <artifactId>mockito-core</artifactId>

+      <version>1.9.5</version>

+      <scope>test</scope>

+      <exclusions>

+        <exclusion>

+          <artifactId>objenesis</artifactId>

+          <groupId>org.objenesis</groupId>

+        </exclusion>

+        <exclusion>

+          <artifactId>hamcrest-core</artifactId>

+          <groupId>org.hamcrest</groupId>

+        </exclusion>

+      </exclusions>

+    </dependency>

+    <dependency>

+      <groupId>com.google.truth</groupId>

+      <artifactId>truth</artifactId>

+      <version>0.26</version>

+      <scope>test</scope>

+    </dependency>

+  </dependencies>

+</project>

+

diff --git a/compiler/pom.xml b/compiler/pom.xml
new file mode 100644
index 0000000..72252f1
--- /dev/null
+++ b/compiler/pom.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2012 Square, Inc.
+ Copyright (C) 2012 Google, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>dagger-compiler</artifactId>
+  <name>Dagger Compiler</name>
+  <description>
+    Tools to generate Dagger injection and module adapters from annotated code and validate them.
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>dagger-producers</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto</groupId>
+      <artifactId>auto-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>com.google.googlejavaformat</groupId>
+      <artifactId>google-java-format</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service</artifactId>
+      <scope>provided</scope> <!-- to leave out of the all-deps jar -->
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <scope>provided</scope> <!-- to leave out of the all-deps jar -->
+      <version>1.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+      <classifier>tests</classifier>
+    </dependency>
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>default-compile</id>
+            <goals><goal>compile</goal></goals>
+            <configuration>
+              <annotationProcessors>
+                <annotationProcessor>com.google.auto.value.processor.AutoValueProcessor</annotationProcessor>
+                <annotationProcessor>com.google.auto.service.processor.AutoServiceProcessor</annotationProcessor>
+              </annotationProcessors>
+            </configuration>
+          </execution>
+          <execution>
+            <id>default-test-compile</id>
+            <goals><goal>testCompile</goal></goals>
+            <configuration>
+              <annotationProcessors>
+                <annotationProcessor>dagger.internal.codegen.ComponentProcessor</annotationProcessor>
+              </annotationProcessors>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-invoker-plugin</artifactId>
+        <configuration>
+          <addTestClassPath>true</addTestClassPath>
+          <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+          <cloneClean>true</cloneClean>
+          <profiles>
+            <profile>!sonatype-oss-release</profile>
+          </profiles>
+          <pomIncludes>
+            <pomInclude>*/pom.xml</pomInclude>
+          </pomIncludes>
+          <localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>
+          <filterProperties>
+            <dagger.version>${project.version}</dagger.version>
+            <dagger.groupId>${project.groupId}</dagger.groupId>
+          </filterProperties>
+          <streamLogs>true</streamLogs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>integration-test</id>
+            <goals>
+              <goal>install</goal>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>2.3</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <minimizeJar>true</minimizeJar>
+              <artifactSet>
+                <excludes>
+                  <!-- guava which has a consistent API and whose public types we vend in producers -->
+                  <exclude>com.google.guava</exclude>
+                  <!-- annotation processors dagger uses to be built, not to operate -->
+                  <exclude>com.google.auto.service</exclude>
+                  <exclude>com.google.auto.value</exclude>
+                  <!-- projects should depend on api projects directly -->
+                  <exclude>com.google.dagger:dagger</exclude>
+                  <exclude>com.google.dagger:dagger-producers</exclude>
+                  <exclude>javax.inject</exclude>
+                </excludes>
+              </artifactSet>
+              <relocations>
+                <relocation>
+                  <pattern>com.google.auto.common</pattern>
+                  <shadedPattern>dagger.shaded.auto.common</shadedPattern>
+                </relocation>
+              </relocations>
+              <filters>
+                <filter>
+                  <artifact>*:*</artifact>
+                  <excludes>
+                    <exclude>META-INF/*.SF</exclude>
+                    <exclude>META-INF/*.DSA</exclude>
+                    <exclude>META-INF/*.RSA</exclude>
+                  </excludes>
+                </filter>
+              </filters>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/compiler/src/it/functional-tests/pom.xml b/compiler/src/it/functional-tests/pom.xml
new file mode 100644
index 0000000..ce3dd4e
--- /dev/null
+++ b/compiler/src/it/functional-tests/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2014 Google, Inc.
+
+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.
+-->
+<project
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+  <groupId>dagger.tests</groupId>
+  <artifactId>functional-tests</artifactId>
+  <name>Functional Tests</name>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject-tck</artifactId>
+    </dependency>
+    <dependency>
+      <!-- For map-bindings -->
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <version>${auto.value.version}</version>
+      <scope>provided</scope> <!-- to leave out of the all-deps jar -->
+    </dependency>
+    <dependency>
+      <!-- For map-bindings -->
+      <groupId>com.google.auto.factory</groupId>
+      <artifactId>auto-factory</artifactId>
+      <version>${auto.factory.version}</version>
+      <scope>provided</scope> <!-- to leave out of the all-deps jar -->
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.1</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.10</version>
+        <configuration>
+          <failsOnError>false</failsOnError>
+          <consoleOutput>true</consoleOutput>
+          <configLocation>../../../../checkstyle.xml</configLocation>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/compiler/src/it/functional-tests/src/main/java/test/A.java b/compiler/src/it/functional-tests/src/main/java/test/A.java
new file mode 100644
index 0000000..030f855
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/A.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class A {
+  @Inject A() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/AbstractMembersInjectingBaseClass.java b/compiler/src/it/functional-tests/src/main/java/test/AbstractMembersInjectingBaseClass.java
new file mode 100644
index 0000000..4fb0f78
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/AbstractMembersInjectingBaseClass.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+abstract class AbstractMembersInjectingBaseClass {
+  @Inject Thing thing;
+}
+
diff --git a/compiler/src/it/functional-tests/src/main/java/test/AbstractMiddleClassWithoutMembers.java b/compiler/src/it/functional-tests/src/main/java/test/AbstractMiddleClassWithoutMembers.java
new file mode 100644
index 0000000..89e94bd
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/AbstractMiddleClassWithoutMembers.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+abstract class AbstractMiddleClassWithoutMembers extends AbstractMembersInjectingBaseClass {
+}
+
diff --git a/compiler/src/it/functional-tests/src/main/java/test/B.java b/compiler/src/it/functional-tests/src/main/java/test/B.java
new file mode 100644
index 0000000..dec8e2e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/B.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class B {
+  @Inject B() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BasicAbstractClassComponent.java b/compiler/src/it/functional-tests/src/main/java/test/BasicAbstractClassComponent.java
new file mode 100644
index 0000000..78f77df
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BasicAbstractClassComponent.java
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.Component;
+
+/**
+ * This component tests behavior equivalent to {@link BasicComponent}, but as an abstract class
+ * rather than an interface.
+ */
+@Component(modules = PrimitivesModule.class)
+abstract class BasicAbstractClassComponent implements BasicComponent {
+  void throwAParty() {
+    throw new RuntimeException("Paaarrrrrtaaaaaaaay!");
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BasicComponent.java b/compiler/src/it/functional-tests/src/main/java/test/BasicComponent.java
new file mode 100644
index 0000000..a04607d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BasicComponent.java
@@ -0,0 +1,81 @@
+/*
+* Copyright (C) 2014 Google, Inc.
+*
+* 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 test;
+
+import dagger.Component;
+import dagger.Lazy;
+import dagger.MembersInjector;
+import javax.inject.Provider;
+
+@Component(modules = PrimitivesModule.class)
+interface BasicComponent extends Injector<Thing> {
+  byte getByte();
+  char getChar();
+  short getShort();
+  int getInt();
+  long getLong();
+  boolean getBoolean();
+  float getFloat();
+  double getDouble();
+
+  Byte getBoxedByte();
+  Character getBoxedChar();
+  Short getBoxedShort();
+  Integer getBoxedInt();
+  Long getBoxedLong();
+  Boolean getBoxedBoolean();
+  Float getBoxedFloat();
+  Double getBoxedDouble();
+
+  Provider<Byte> getByteProvider();
+  Provider<Character> getCharProvider();
+  Provider<Short> getShortProvider();
+  Provider<Integer> getIntProvider();
+  Provider<Long> getLongProvider();
+  Provider<Boolean> getBooleanProvider();
+  Provider<Float> getFloatProvider();
+  Provider<Double> getDoubleProvider();
+
+  byte[] getByteArray();
+  char[] getCharArray();
+  short[] getShortArray();
+  int[] getIntArray();
+  long[] getLongArray();
+  boolean[] getBooleanArray();
+  float[] getFloatArray();
+  double[] getDoubleArray();
+
+  Provider<byte[]> getByteArrayProvider();
+  Provider<char[]> getCharArrayProvider();
+  Provider<short[]> getShortArrayProvider();
+  Provider<int[]> getIntArrayProvider();
+  Provider<long[]> getLongArrayProvider();
+  Provider<boolean[]> getBooleanArrayProvider();
+  Provider<float[]> getFloatArrayProvider();
+  Provider<double[]> getDoubleArrayProvider();
+
+  Object noOpMembersInjection(Object obviouslyDoesNotHaveMembersToInject);
+
+  Thing thing();
+  InjectedThing injectedThing();
+  Provider<InjectedThing> injectedThingProvider();
+  Lazy<InjectedThing> lazyInjectedThing();
+  MembersInjector<InjectedThing> injectedThingMembersInjector();
+
+  TypeWithInheritedMembersInjection typeWithInheritedMembersInjection();
+  MembersInjector<TypeWithInheritedMembersInjection>
+      typeWithInheritedMembersInjectionMembersInjector();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BooleanKey.java b/compiler/src/it/functional-tests/src/main/java/test/BooleanKey.java
new file mode 100644
index 0000000..4cef79e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BooleanKey.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+@MapKey(unwrapValue = true)
+@interface BooleanKey {
+  boolean value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericComponent.java b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericComponent.java
new file mode 100644
index 0000000..b30522f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Component;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+@Component(modules = BoundedGenericModule.class)
+interface BoundedGenericComponent {
+  BoundedGenerics<Integer, ArrayList<String>, LinkedList<CharSequence>, Integer, List<Integer>>
+      bounds1();
+  BoundedGenerics<Double, LinkedList<String>, LinkedList<Comparable<String>>, Double, Set<Double>>
+      bounds2();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericModule.java b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericModule.java
new file mode 100644
index 0000000..6bd7be4
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenericModule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+@Module
+class BoundedGenericModule {
+
+  @Provides
+  Integer provideInteger() {
+    return 1;
+  }
+
+  @Provides
+  Double provideDouble() {
+    return 2d;
+  }
+
+  @Provides
+  ArrayList<String> provideArrayListString() {
+    ArrayList<String> list = new ArrayList<>();
+    list.add("arrayListOfString");
+    return list;
+  }
+
+  @Provides
+  LinkedList<String> provideLinkedListString() {
+    LinkedList<String> list = new LinkedList<>();
+    list.add("linkedListOfString");
+    return list;
+  }
+
+  @Provides
+  LinkedList<CharSequence> provideLinkedListCharSeq() {
+    LinkedList<CharSequence> list = new LinkedList<>();
+    list.add("linkedListOfCharSeq");
+    return list;
+  }
+
+  @Provides
+  @SuppressWarnings("unchecked")
+  LinkedList<Comparable<String>> provideArrayListOfComparableString() {
+    LinkedList<Comparable<String>> list = new LinkedList<>();
+    list.add("arrayListOfComparableOfString");
+    return list;
+  }
+
+  @Provides
+  List<Integer> provideListOfInteger() {
+    LinkedList<Integer> list = new LinkedList<>();
+    list.add(3);
+    return list;
+  }
+
+  @Provides
+  Set<Double> provideSetOfDouble() {
+    Set<Double> set = new HashSet<>();
+    set.add(4d);
+    return set;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/BoundedGenerics.java b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenerics.java
new file mode 100644
index 0000000..e26d643
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/BoundedGenerics.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import java.util.List;
+import javax.inject.Inject;
+
+class BoundedGenerics<A extends Number & Comparable<? super A>, 
+      B extends List<? extends CharSequence>,
+      C extends List<? super String>,
+      D extends A,
+      E extends Iterable<D>> {
+  
+  final A a;
+  final B b;
+  final C c;
+  final D d;
+  final E e;
+  
+  @Inject BoundedGenerics(A a, B b, C c, D d, E e) {
+    this.a = a;
+    this.b = b;
+    this.c = c;
+    this.d = d;
+    this.e = e;
+  }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ByteKey.java b/compiler/src/it/functional-tests/src/main/java/test/ByteKey.java
new file mode 100644
index 0000000..8e739bd
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ByteKey.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+@MapKey(unwrapValue = true)
+@interface ByteKey {
+  byte value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/CharKey.java b/compiler/src/it/functional-tests/src/main/java/test/CharKey.java
new file mode 100644
index 0000000..a4f4e29
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/CharKey.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+@MapKey(unwrapValue = true)
+@interface CharKey {
+  char value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ChildDoubleModule.java b/compiler/src/it/functional-tests/src/main/java/test/ChildDoubleModule.java
new file mode 100644
index 0000000..09a1e6b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ChildDoubleModule.java
@@ -0,0 +1,21 @@
+package test;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.ArrayList;
+import java.util.List;
+
+@Module
+class ChildDoubleModule extends ParentModule<Double, String, List<Double>> {
+
+  @Provides Double provideDouble() {
+    return 3d;
+  }
+
+  @Provides List<Double> provideListOfDouble() {
+    List<Double> list = new ArrayList<>();
+    list.add(4d);
+    return list;
+  }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ChildIntegerModule.java b/compiler/src/it/functional-tests/src/main/java/test/ChildIntegerModule.java
new file mode 100644
index 0000000..ac9c612
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ChildIntegerModule.java
@@ -0,0 +1,21 @@
+package test;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.ArrayList;
+import java.util.List;
+
+@Module
+class ChildIntegerModule extends ParentModule<Integer, String, List<Integer>> {
+
+  @Provides Integer provideInteger() {
+    return 1;
+  }
+
+  @Provides List<Integer> provideListOfInteger() {
+    List<Integer> list = new ArrayList<>();
+    list.add(2);
+    return list;
+  }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ComplexGenerics.java b/compiler/src/it/functional-tests/src/main/java/test/ComplexGenerics.java
new file mode 100644
index 0000000..e2e3274
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ComplexGenerics.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Lazy;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+class ComplexGenerics {
+  
+  final Generic2<Generic<A>> g2ga;
+  final Lazy<Generic2<Generic<A>>> g2gaLazy;
+  final Provider<Generic2<Generic<A>>> g2gaProvider;
+  final Generic2<Generic<B>> g2gb;
+  final Lazy<Generic2<Generic<B>>> g2gbLazy;
+  final Provider<Generic2<Generic<B>>> g2gbProvider;
+  final Generic2<A> g2a;
+  final Generic<Generic2<A>> gg2a;
+  final Generic<Generic2<B>> gg2b;
+  
+  @Inject ComplexGenerics(
+      Generic2<Generic<A>> g2ga,
+      Lazy<Generic2<Generic<A>>> g2gaLazy,
+      Provider<Generic2<Generic<A>>> g2gaProvider,
+      Generic2<Generic<B>> g2gb,
+      Lazy<Generic2<Generic<B>>> g2gbLazy,
+      Provider<Generic2<Generic<B>>> g2gbProvider,
+      Generic2<A> g2a,
+      Generic<Generic2<A>> gg2a,
+      Generic<Generic2<B>> gg2b) {
+    this.g2ga = g2ga;
+    this.g2gaLazy = g2gaLazy;
+    this.g2gaProvider = g2gaProvider;
+    this.g2gb = g2gb;
+    this.g2gbLazy = g2gbLazy;
+    this.g2gbProvider = g2gbProvider;
+    this.g2a = g2a;
+    this.gg2a = gg2a;
+    this.gg2b = gg2b;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ComponentDependsOnGeneratedCode.java b/compiler/src/it/functional-tests/src/main/java/test/ComponentDependsOnGeneratedCode.java
new file mode 100644
index 0000000..6ffe1e0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ComponentDependsOnGeneratedCode.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.Component;
+
+@Component
+interface ComponentDependsOnGeneratedCode {
+  NeedsFactory needsFactory();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCode.java b/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCode.java
new file mode 100644
index 0000000..f7460c9
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCode.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Component;
+
+@Component
+interface ComponentSupertypeDependsOnGeneratedCode
+    extends ComponentSupertypeDependsOnGeneratedCodeInterface {}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCodeInterface.java b/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCodeInterface.java
new file mode 100644
index 0000000..fca90e0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ComponentSupertypeDependsOnGeneratedCodeInterface.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+interface ComponentSupertypeDependsOnGeneratedCodeInterface {
+  NeedsFactory_SomethingFactory somethingFactory();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/Generic.java b/compiler/src/it/functional-tests/src/main/java/test/Generic.java
new file mode 100644
index 0000000..ee1aa09
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/Generic.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+public class Generic<T> {
+  final T t;
+
+  @Inject public Generic(T t) {
+    this.t = t;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/Generic2.java b/compiler/src/it/functional-tests/src/main/java/test/Generic2.java
new file mode 100644
index 0000000..4a56df3
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/Generic2.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+public class Generic2<T> {
+  final T t;
+
+  @Inject Generic2(T t) {
+    this.t = t;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/GenericChild.java b/compiler/src/it/functional-tests/src/main/java/test/GenericChild.java
new file mode 100644
index 0000000..5c65dc0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/GenericChild.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class GenericChild<T> extends GenericParent<T, B> {
+  
+  A registeredA;
+  T registeredT;
+  
+  @Inject GenericChild() {}
+  
+  @Inject A a;
+  @Inject T t;
+  
+  @Inject void registerA(A a) { this.registeredA = a; }
+  @Inject void registerT(T t) { this.registeredT = t; }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/GenericComponent.java b/compiler/src/it/functional-tests/src/main/java/test/GenericComponent.java
new file mode 100644
index 0000000..da5b9b5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/GenericComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Component;
+import test.sub.Exposed;
+import test.sub.PublicSubclass;
+
+@Component(modules = {ChildDoubleModule.class, ChildIntegerModule.class})
+interface GenericComponent {
+  ReferencesGeneric referencesGeneric();
+  GenericDoubleReferences<A> doubleGenericA();
+  GenericDoubleReferences<B> doubleGenericB();
+  ComplexGenerics complexGenerics();
+  GenericNoDeps<A> noDepsA();
+  GenericNoDeps<B> noDepsB();
+
+  void injectA(GenericChild<A> childA);
+  void injectB(GenericChild<B> childB);
+
+  Exposed exposed();
+  PublicSubclass publicSubclass();
+  
+  Iterable<Integer> iterableInt();
+  Iterable<Double> iterableDouble();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/GenericDoubleReferences.java b/compiler/src/it/functional-tests/src/main/java/test/GenericDoubleReferences.java
new file mode 100644
index 0000000..6785c7c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/GenericDoubleReferences.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class GenericDoubleReferences<T> {
+  final T t;
+  final T t2;
+  final Thing a;
+  final Thing a2;
+
+  @Inject GenericDoubleReferences(T t, Thing a, T t2, Thing a2) {
+    this.t = t;
+    this.a = a;
+    this.t2 = t2;
+    this.a2 = a2;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/GenericNoDeps.java b/compiler/src/it/functional-tests/src/main/java/test/GenericNoDeps.java
new file mode 100644
index 0000000..e065f79
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/GenericNoDeps.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class GenericNoDeps<T> {
+  
+  @Inject GenericNoDeps() {}
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/GenericParent.java b/compiler/src/it/functional-tests/src/main/java/test/GenericParent.java
new file mode 100644
index 0000000..0e01f5f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/GenericParent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class GenericParent<X, Y> {
+  
+  X registeredX;
+  Y registeredY;
+  B registeredB;
+  
+  
+  @Inject GenericParent() {}
+  
+  @Inject X x;
+  @Inject Y y;
+  @Inject B b;
+  
+  @Inject void registerX(X x) { this.registeredX = x; }
+  @Inject void registerY(Y y) { this.registeredY = y; }
+  @Inject void registerB(B b) { this.registeredB = b; }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/InjectedThing.java b/compiler/src/it/functional-tests/src/main/java/test/InjectedThing.java
new file mode 100644
index 0000000..73a46e8
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/InjectedThing.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Lazy;
+import dagger.MembersInjector;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@SuppressWarnings("unused")
+final class InjectedThing {
+  @Inject byte primitiveByte;
+  @Inject char primitiveChar;
+  @Inject short primitiveShort;
+  @Inject int primitiveInt;
+  @Inject long primitiveLong;
+  @Inject boolean primitiveBoolean;
+  @Inject float primitiveFloat;
+  @Inject double primitiveDouble;
+
+  @Inject Provider<Byte> byteProvider;
+  @Inject Provider<Character> charProvider;
+  @Inject Provider<Short> shortProvider;
+  @Inject Provider<Integer> intProvider;
+  @Inject Provider<Long> longProvider;
+  @Inject Provider<Boolean> booleanProvider;
+  @Inject Provider<Float> floatProvider;
+  @Inject Provider<Double> doubleProvider;
+
+  @Inject Lazy<Byte> lazyByte;
+  @Inject Lazy<Character> lazyChar;
+  @Inject Lazy<Short> lazyShort;
+  @Inject Lazy<Integer> lazyInt;
+  @Inject Lazy<Long> lazyLong;
+  @Inject Lazy<Boolean> lazyBoolean;
+  @Inject Lazy<Float> lazyFloat;
+  @Inject Lazy<Double> lazyDouble;
+
+  @Inject Byte boxedBype;
+  @Inject Character boxedChar;
+  @Inject Short boxedShort;
+  @Inject Integer boxedInt;
+  @Inject Long boxedLong;
+  @Inject Boolean boxedBoolean;
+  @Inject Float boxedFloat;
+  @Inject Double boxedDouble;
+
+  @Inject byte[] byteArray;
+  @Inject char[] charArray;
+  @Inject short[] shortArray;
+  @Inject int[] intArray;
+  @Inject long[] longArray;
+  @Inject boolean[] booleanArray;
+  @Inject float[] floatArray;
+  @Inject double[] doubleArray;
+
+  @Inject Provider<byte[]> byteArrayProvider;
+  @Inject Provider<char[]> charArrayProvider;
+  @Inject Provider<short[]> shortArrayProvider;
+  @Inject Provider<int[]> intArrayProvider;
+  @Inject Provider<long[]> longArrayProvider;
+  @Inject Provider<boolean[]> booleanArrayProvider;
+  @Inject Provider<float[]> floatArrayProvider;
+  @Inject Provider<double[]> doubleArrayProvider;
+
+  @Inject Lazy<byte[]> lazyByteArray;
+  @Inject Lazy<char[]> lazyCharArray;
+  @Inject Lazy<short[]> lazyShortArray;
+  @Inject Lazy<int[]> lazyIntArray;
+  @Inject Lazy<long[]> lazyLongArray;
+  @Inject Lazy<boolean[]> lazyBooleanArray;
+  @Inject Lazy<float[]> lazy;
+  @Inject Lazy<double[]> lazyDoubleArray;
+
+  @Inject Thing thing;
+  @Inject Provider<Thing> thingProvider;
+  @Inject Lazy<Thing> lazyThing;
+  @Inject MembersInjector<Thing> thingMembersInjector;
+
+  @Inject InjectedThing(
+      byte primitiveByte,
+      char primitiveChar,
+      short primitiveShort,
+      int primitiveInt,
+      long primitiveLong,
+      boolean primitiveBoolean,
+      float primitiveFloat,
+      double primitiveDouble,
+
+      Provider<Byte> byteProvider,
+      Provider<Character> charProvider,
+      Provider<Short> shortProvider,
+      Provider<Integer> intProvider,
+      Provider<Long> longProvider,
+      Provider<Boolean> booleanProvider,
+      Provider<Float> floatProvider,
+      Provider<Double> doubleProvider,
+
+      Lazy<Byte> lazyByte,
+      Lazy<Character> lazyChar,
+      Lazy<Short> lazyShort,
+      Lazy<Integer> lazyInt,
+      Lazy<Long> lazyLong,
+      Lazy<Boolean> lazyBoolean,
+      Lazy<Float> lazyFloat,
+      Lazy<Double> lazyDouble,
+
+      Byte boxedBype,
+      Character boxedChar,
+      Short boxedShort,
+      Integer boxedInt,
+      Long boxedLong,
+      Boolean boxedBoolean,
+      Float boxedFloat,
+      Double boxedDouble,
+
+      byte[] byteArray,
+      char[] charArray,
+      short[] shortArray,
+      int[] intArray,
+      long[] longArray,
+      boolean[] booleanArray,
+      float[] floatArray,
+      double[] doubleArray,
+
+      Provider<byte[]> byteArrayProvider,
+      Provider<char[]> charArrayProvider,
+      Provider<short[]> shortArrayProvider,
+      Provider<int[]> intArrayProvider,
+      Provider<long[]> longArrayProvider,
+      Provider<boolean[]> booleanArrayProvider,
+      Provider<float[]> floatArrayProvider,
+      Provider<double[]> doubleArrayProvider,
+
+      Lazy<byte[]> lazyByteArray,
+      Lazy<char[]> lazyCharArray,
+      Lazy<short[]> lazyShortArray,
+      Lazy<int[]> lazyIntArray,
+      Lazy<long[]> lazyLongArray,
+      Lazy<boolean[]> lazyBooleanArray,
+      Lazy<float[]> lazy,
+      Lazy<double[]> lazyDoubleArray,
+
+      Thing thing,
+      Provider<Thing> thingProvider,
+      Lazy<Thing> lazyThing,
+      MembersInjector<Thing> thingMembersInjector) {}
+
+  @Inject void primitiveByte(byte primitiveByte) {}
+  @Inject void primitiveChar(char primitiveChar) {}
+  @Inject void primitiveShort(short primitiveShort) {}
+  @Inject void primitiveInt(int primitiveInt) {}
+  @Inject void primitiveLong(long primitiveLong) {}
+  @Inject void primitiveBoolean(boolean primitiveBoolean) {}
+  @Inject void primitiveFloat(float primitiveFloat) {}
+  @Inject void primitiveDouble(double primitiveDouble) {}
+
+  @Inject void byteProvider(Provider<Byte> byteProvider) {}
+  @Inject void charProvider(Provider<Character> charProvider) {}
+  @Inject void shortProvider(Provider<Short> shortProvider) {}
+  @Inject void intProvider(Provider<Integer> intProvider) {}
+  @Inject void longProvider(Provider<Long> longProvider) {}
+  @Inject void booleanProvider(Provider<Boolean> booleanProvider) {}
+  @Inject void floatProvider(Provider<Float> floatProvider) {}
+  @Inject void doubleProvider(Provider<Double> doubleProvider) {}
+
+  @Inject void lazyByte(Lazy<Byte> lazyByte) {}
+  @Inject void lazyChar(Lazy<Character> lazyChar) {}
+  @Inject void lazyShort(Lazy<Short> lazyShort) {}
+  @Inject void lazyInt(Lazy<Integer> lazyInt) {}
+  @Inject void lazyLong(Lazy<Long> lazyLong) {}
+  @Inject void lazyBoolean(Lazy<Boolean> lazyBoolean) {}
+  @Inject void lazyFloat(Lazy<Float> lazyFloat) {}
+  @Inject void lazyDouble(Lazy<Double> lazyDouble) {}
+
+  @Inject void boxedBype(Byte boxedBype) {}
+  @Inject void boxedChar(Character boxedChar) {}
+  @Inject void boxedShort(Short boxedShort) {}
+  @Inject void boxedInt(Integer boxedInt) {}
+  @Inject void boxedLong(Long boxedLong) {}
+  @Inject void boxedBoolean(Boolean boxedBoolean) {}
+  @Inject void boxedFloat(Float boxedFloat) {}
+  @Inject void boxedDouble(Double boxedDouble) {}
+
+  @Inject void byteArray(byte[] byteArray) {}
+  @Inject void charArray(char[] charArray) {}
+  @Inject void shortArray(short[] shortArray) {}
+  @Inject void intArray(int[] intArray) {}
+  @Inject void longArray(long[] longArray) {}
+  @Inject void booleanArray(boolean[] booleanArray) {}
+  @Inject void floatArray(float[] floatArray) {}
+  @Inject void doubleArray(double[] doubleArray) {}
+
+  @Inject void byteArrayProvider(Provider<byte[]> byteArrayProvider) {}
+  @Inject void charArrayProvider(Provider<char[]> charArrayProvider) {}
+  @Inject void shortArrayProvider(Provider<short[]> shortArrayProvider) {}
+  @Inject void intArrayProvider(Provider<int[]> intArrayProvider) {}
+  @Inject void longArrayProvider(Provider<long[]> longArrayProvider) {}
+  @Inject void booleanArrayProvider(Provider<boolean[]> booleanArrayProvider) {}
+  @Inject void floatArrayProvider(Provider<float[]> floatArrayProvider) {}
+  @Inject void doubleArrayProvider(Provider<double[]> doubleArrayProvider) {}
+
+  @Inject void lazyByteArray(Lazy<byte[]> lazyByteArray) {}
+  @Inject void lazyCharArray(Lazy<char[]> lazyCharArray) {}
+  @Inject void lazyShortArray(Lazy<short[]> lazyShortArray) {}
+  @Inject void lazyIntArray(Lazy<int[]> lazyIntArray) {}
+  @Inject void lazyLongArray(Lazy<long[]> lazyLongArray) {}
+  @Inject void lazyBooleanArray(Lazy<boolean[]> lazyBooleanArray) {}
+  @Inject void lazy(Lazy<float[]> lazy) {}
+  @Inject void lazyDoubleArray(Lazy<double[]> lazyDoubleArray) {}
+
+  @Inject void thing(Thing thing) {}
+  @Inject void thingProvider(Provider<Thing> thingProvider) {}
+  @Inject void lazyThing(Lazy<Thing> lazyThing) {}
+  @Inject void thingMembersInjector(MembersInjector<Thing> thingMembersInjector) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/Injector.java b/compiler/src/it/functional-tests/src/main/java/test/Injector.java
new file mode 100644
index 0000000..2a5798a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/Injector.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Lazy;
+import dagger.MembersInjector;
+import javax.inject.Provider;
+
+/**
+ * A simple interface that exercises all forms of injection for a given type.
+ */
+interface Injector<T> {
+  T instance();
+  Provider<T> provider();
+  Lazy<T> lazy();
+  MembersInjector<T> membersInjector();
+  void injectMembers(T t);
+  T injectMembersAndReturn(T t);
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/MultibindingComponent.java b/compiler/src/it/functional-tests/src/main/java/test/MultibindingComponent.java
new file mode 100644
index 0000000..ac0624f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/MultibindingComponent.java
@@ -0,0 +1,53 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.Component;
+import dagger.mapkeys.StringKey;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Named;
+import javax.inject.Provider;
+import test.sub.ContributionsModule;
+
+@Component(
+  modules = {
+    MultibindingModule.class,
+    ContributionsModule.class
+  },
+  dependencies = MultibindingDependency.class
+)
+interface MultibindingComponent {
+  Map<String, String> map();
+  Map<String, String[]> mapOfArrays();
+  Map<String, Provider<String>> mapOfProviders();
+  Set<String> mapKeys();
+  Collection<String> mapValues();
+  Set<Integer> set();
+  Map<NestedAnnotationContainer.NestedWrappedKey, String> nestedKeyMap();
+  Map<Class<? extends Number>, String> numberClassKeyMap();
+  Map<Class<?>, String> classKeyMap();
+  Map<Long, String> longKeyMap();
+  Map<Integer, String> integerKeyMap();
+  Map<Short, String> shortKeyMap();
+  Map<Byte, String> byteKeyMap();
+  Map<Boolean, String> booleanKeyMap();
+  Map<Character, String> characterKeyMap();
+  Map<StringKey, String> unwrappedAnnotationKeyMap();
+  Map<WrappedAnnotationKey, String> wrappedAnnotationKeyMap();
+  @Named("complexQualifier") Set<String> complexQualifierStringSet();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/MultibindingDependency.java b/compiler/src/it/functional-tests/src/main/java/test/MultibindingDependency.java
new file mode 100644
index 0000000..a92e029
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/MultibindingDependency.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+interface MultibindingDependency {
+  double doubleDependency();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/MultibindingModule.java b/compiler/src/it/functional-tests/src/main/java/test/MultibindingModule.java
new file mode 100644
index 0000000..4a7577e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/MultibindingModule.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.mapkeys.ClassKey;
+import dagger.mapkeys.IntKey;
+import dagger.mapkeys.LongKey;
+import dagger.mapkeys.StringKey;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Named;
+import javax.inject.Provider;
+
+import static dagger.Provides.Type.MAP;
+import static dagger.Provides.Type.SET;
+
+@Module
+class MultibindingModule {
+  @Provides(type = MAP)
+  @StringKey("foo")
+  static String provideFooKey(double doubleDependency) {
+    return "foo value";
+  }
+
+  @Provides(type = MAP)
+  @StringKey("bar")
+  static String provideBarKey() {
+    return "bar value";
+  }
+
+  @Provides(type = MAP)
+  @StringKey("foo")
+  static String[] provideFooArrayValue(double doubleDependency) {
+    return new String[] {"foo1", "foo2"};
+  }
+
+  @Provides(type = MAP)
+  @StringKey("bar")
+  static String[] provideBarArrayValue() {
+    return new String[] {"bar1", "bar2"};
+  }
+
+  @Provides(type = SET)
+  static int provideFiveToSet() {
+    return 5;
+  }
+
+  @Provides(type = SET)
+  static int provideSixToSet() {
+    return 6;
+  }
+
+  @Provides
+  static Set<String> provideMapKeys(Map<String, Provider<String>> map) {
+    return map.keySet();
+  }
+
+  @Provides
+  static Collection<String> provideMapValues(Map<String, String> map) {
+    return map.values();
+  }
+
+  @Provides(type = MAP)
+  @NestedAnnotationContainer.NestedWrappedKey(Integer.class)
+  static String valueForInteger() {
+    return "integer";
+  }
+
+  @Provides(type = MAP)
+  @NestedAnnotationContainer.NestedWrappedKey(Long.class)
+  static String valueForLong() {
+    return "long";
+  }
+
+  @Provides(type = MAP)
+  @ClassKey(Integer.class)
+  static String valueForClassInteger() {
+    return "integer";
+  }
+
+  @Provides(type = MAP)
+  @ClassKey(Long.class)
+  static String valueForClassLong() {
+    return "long";
+  }
+
+  @Provides(type = MAP)
+  @NumberClassKey(BigDecimal.class)
+  static String valueForNumberClassBigDecimal() {
+    return "bigdecimal";
+  }
+
+  @Provides(type = MAP)
+  @NumberClassKey(BigInteger.class)
+  static String valueForNumberClassBigInteger() {
+    return "biginteger";
+  }
+
+  @Provides(type = MAP)
+  @LongKey(100)
+  static String valueFor100Long() {
+    return "100 long";
+  }
+
+  @Provides(type = MAP)
+  @IntKey(100)
+  static String valueFor100Int() {
+    return "100 int";
+  }
+
+  @Provides(type = MAP)
+  @ShortKey(100)
+  static String valueFor100Short() {
+    return "100 short";
+  }
+
+  @Provides(type = MAP)
+  @ByteKey(100)
+  static String valueFor100Byte() {
+    return "100 byte";
+  }
+
+  @Provides(type = MAP)
+  @BooleanKey(true)
+  static String valueForTrue() {
+    return "true";
+  }
+
+  @Provides(type = MAP)
+  @CharKey('a')
+  static String valueForA() {
+    return "a char";
+  }
+
+  @Provides(type = MAP)
+  @CharKey('\n')
+  static String valueForNewline() {
+    return "newline char";
+  }
+
+  @Provides(type = MAP)
+  @UnwrappedAnnotationKey(@StringKey("foo\n"))
+  static String valueForUnwrappedAnnotationKeyFoo() {
+    return "foo annotation";
+  }
+
+  @Provides(type = MAP)
+  @WrappedAnnotationKey(
+    value = @StringKey("foo"),
+    integers = {1, 2, 3},
+    annotations = {},
+    classes = {Long.class, Integer.class}
+  )
+  static String valueForWrappedAnnotationKeyFoo() {
+    return "wrapped foo annotation";
+  }
+
+  @Provides(type = SET)
+  @Named("complexQualifier")
+  static String valueForComplexQualifierSet() {
+    return "foo";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/NeedsFactory.java b/compiler/src/it/functional-tests/src/main/java/test/NeedsFactory.java
new file mode 100644
index 0000000..b789073
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/NeedsFactory.java
@@ -0,0 +1,27 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import com.google.auto.factory.AutoFactory;
+import javax.inject.Inject;
+
+class NeedsFactory {
+  @Inject NeedsFactory(NeedsFactory_SomethingFactory somethingFactory) {}
+
+  @AutoFactory
+  static class Something {}
+}
+
diff --git a/compiler/src/it/functional-tests/src/main/java/test/NestedAnnotationContainer.java b/compiler/src/it/functional-tests/src/main/java/test/NestedAnnotationContainer.java
new file mode 100644
index 0000000..c57b4ec
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/NestedAnnotationContainer.java
@@ -0,0 +1,26 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+public final class NestedAnnotationContainer {
+
+  @MapKey(unwrapValue = false)
+  @interface NestedWrappedKey {
+    Class<?> value();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/NonComponentDependencyComponent.java b/compiler/src/it/functional-tests/src/main/java/test/NonComponentDependencyComponent.java
new file mode 100644
index 0000000..43a088c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/NonComponentDependencyComponent.java
@@ -0,0 +1,47 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.Component;
+import javax.inject.Inject;
+import test.sub.OtherThing;
+
+@Component(dependencies = {NonComponentDependencyComponent.ThingComponent.class})
+interface NonComponentDependencyComponent {
+  ThingTwo thingTwo();
+
+  static class ThingTwo {
+    @SuppressWarnings("unused")
+    @Inject
+    ThingTwo(
+        Thing thing,
+        NonComponentDependencyComponent nonComponentDependencyComponent,
+        NonComponentDependencyComponent.ThingComponent thingComponent) {}
+  }
+
+  // A non-component interface which this interface depends upon.
+  interface ThingComponent {
+    Thing thing();
+  }
+
+  // The implementation for that interface.
+  static class ThingComponentImpl implements ThingComponent {
+    @Override
+    public Thing thing() {
+      return new Thing(new OtherThing(1));
+    }
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/NumberClassKey.java b/compiler/src/it/functional-tests/src/main/java/test/NumberClassKey.java
new file mode 100644
index 0000000..4164ae5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/NumberClassKey.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+@MapKey(unwrapValue = true)
+@interface NumberClassKey {
+  Class<? extends Number> value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/OuterClassBar.java b/compiler/src/it/functional-tests/src/main/java/test/OuterClassBar.java
new file mode 100644
index 0000000..c7fabdb
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/OuterClassBar.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Component;
+
+final class OuterClassBar {
+  @Component(modules = PrimitivesModule.class)
+  interface NestedComponent {
+    InjectedThing injectedThing();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/OuterClassFoo.java b/compiler/src/it/functional-tests/src/main/java/test/OuterClassFoo.java
new file mode 100644
index 0000000..86f963f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/OuterClassFoo.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import dagger.Component;
+
+final class OuterClassFoo {
+  @Component(modules = PrimitivesModule.class)
+  interface NestedComponent {
+    Thing thing();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ParentModule.java b/compiler/src/it/functional-tests/src/main/java/test/ParentModule.java
new file mode 100644
index 0000000..a161aba
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ParentModule.java
@@ -0,0 +1,18 @@
+package test;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.ArrayList;
+import java.util.List;
+
+@Module
+abstract class ParentModule<A extends Number & Comparable<A>, B, C extends Iterable<A>> {
+  @Provides Iterable<A> provideIterableOfAWithC(A a, C c) {
+    List<A> list = new ArrayList<>();
+    list.add(a);
+    for (A elt : c) {
+      list.add(elt);
+    }
+    return list;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/PrimitivesModule.java b/compiler/src/it/functional-tests/src/main/java/test/PrimitivesModule.java
new file mode 100644
index 0000000..acbf271
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/PrimitivesModule.java
@@ -0,0 +1,93 @@
+package test;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class PrimitivesModule {
+  static final byte BOUND_BYTE = -41;
+  static final char BOUND_CHAR = 'g';
+  static final short BOUND_SHORT = 21840;
+  static final int BOUND_INT = 1894833693;
+  static final long BOUND_LONG = -4369839828653523584L;
+  static final boolean BOUND_BOOLEAN = true;
+  static final float BOUND_FLOAT = (float) 0.9964542;
+  static final double BOUND_DOUBLE = 0.12681322049667765;
+
+  /*
+   * While we can't ensure that these constants stay constant, this is a test so we're just going to
+   * keep our fingers crossed that we're not going to be jerks.
+   */
+  static final byte[] BOUND_BYTE_ARRAY =  {1, 2, 3};
+  static final char[] BOUND_CHAR_ARRAY = {'g', 'a', 'k'};
+  static final short[] BOUND_SHORT_ARRAY = {2, 4};
+  static final int[] BOUND_INT_ARRAY = {3, 1, 2};
+  static final long[] BOUND_LONG_ARRAY = {1, 1, 2, 3, 5};
+  static final boolean[] BOUND_BOOLEAN_ARRAY = {false, true, false, false};
+  static final float[] BOUND_FLOAT_ARRAY = {(float) 0.1, (float) 0.01, (float) 0.001};
+  static final double[] BOUND_DOUBLE_ARRAY = {0.2, 0.02, 0.002};
+
+  @Provides static byte provideByte() {
+    return BOUND_BYTE;
+  }
+
+  @Provides static char provideChar() {
+    return BOUND_CHAR;
+  }
+
+  @Provides static short provideShort() {
+    return BOUND_SHORT;
+  }
+
+  @Provides static int provideInt() {
+    return BOUND_INT;
+  }
+
+  @Provides static long provideLong() {
+    return BOUND_LONG;
+  }
+
+  @Provides static boolean provideBoolean() {
+    return BOUND_BOOLEAN;
+  }
+
+  @Provides static float provideFloat() {
+    return BOUND_FLOAT;
+  }
+
+  @Provides static double boundDouble() {
+    return BOUND_DOUBLE;
+  }
+
+  @Provides static byte[] provideByteArray() {
+    return BOUND_BYTE_ARRAY;
+  }
+
+  @Provides static char[] provideCharArray() {
+    return BOUND_CHAR_ARRAY;
+  }
+
+  @Provides static short[] provideShortArray() {
+    return BOUND_SHORT_ARRAY;
+  }
+
+  @Provides static int[] provideIntArray() {
+    return BOUND_INT_ARRAY;
+  }
+
+  @Provides static long[] provideLongArray() {
+    return BOUND_LONG_ARRAY;
+  }
+
+  @Provides static boolean[] provideBooleanArray() {
+    return BOUND_BOOLEAN_ARRAY;
+  }
+
+  @Provides static float[] provideFloatArray() {
+    return BOUND_FLOAT_ARRAY;
+  }
+
+  @Provides static double[] boundDoubleArray() {
+    return BOUND_DOUBLE_ARRAY;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ReferencesGeneric.java b/compiler/src/it/functional-tests/src/main/java/test/ReferencesGeneric.java
new file mode 100644
index 0000000..812c45d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ReferencesGeneric.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+class ReferencesGeneric {
+  final Generic<A> genericA;
+  
+  @Inject ReferencesGeneric(Generic<A> genericA) {
+    this.genericA = genericA;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ScopedGeneric.java b/compiler/src/it/functional-tests/src/main/java/test/ScopedGeneric.java
new file mode 100644
index 0000000..37d68e0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ScopedGeneric.java
@@ -0,0 +1,12 @@
+package test;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+class ScopedGeneric<T> { 
+  final T t;  
+  @Inject ScopedGeneric(T t) {
+    this.t = t;
+  }  
+}
\ No newline at end of file
diff --git a/compiler/src/it/functional-tests/src/main/java/test/ShortKey.java b/compiler/src/it/functional-tests/src/main/java/test/ShortKey.java
new file mode 100644
index 0000000..01b3aa9
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/ShortKey.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+
+@MapKey(unwrapValue = true)
+@interface ShortKey {
+  short value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/SingletonGenericComponent.java b/compiler/src/it/functional-tests/src/main/java/test/SingletonGenericComponent.java
new file mode 100644
index 0000000..44a2cb5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/SingletonGenericComponent.java
@@ -0,0 +1,13 @@
+package test;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Singleton
+@Component
+interface SingletonGenericComponent {
+  
+  ScopedGeneric<A> scopedGenericA();
+  ScopedGeneric<B> scopedGenericB();
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/Thing.java b/compiler/src/it/functional-tests/src/main/java/test/Thing.java
new file mode 100644
index 0000000..46cbdc9
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/Thing.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2014 Google, Inc.
+*
+* 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 test;
+
+import javax.inject.Inject;
+import test.sub.OtherThing;
+
+final class Thing {
+  @Inject Thing(@SuppressWarnings("unused") OtherThing unused) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/TypeWithInheritedMembersInjection.java b/compiler/src/it/functional-tests/src/main/java/test/TypeWithInheritedMembersInjection.java
new file mode 100644
index 0000000..587baad
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/TypeWithInheritedMembersInjection.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import javax.inject.Inject;
+
+final class TypeWithInheritedMembersInjection extends AbstractMiddleClassWithoutMembers {
+  @Inject TypeWithInheritedMembersInjection() {}
+}
+
diff --git a/compiler/src/it/functional-tests/src/main/java/test/UnwrappedAnnotationKey.java b/compiler/src/it/functional-tests/src/main/java/test/UnwrappedAnnotationKey.java
new file mode 100644
index 0000000..21ed958
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/UnwrappedAnnotationKey.java
@@ -0,0 +1,24 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+import dagger.mapkeys.StringKey;
+
+@MapKey(unwrapValue = true)
+@interface UnwrappedAnnotationKey {
+  StringKey value();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/WrappedAnnotationKey.java b/compiler/src/it/functional-tests/src/main/java/test/WrappedAnnotationKey.java
new file mode 100644
index 0000000..5d6e86d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/WrappedAnnotationKey.java
@@ -0,0 +1,28 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import dagger.MapKey;
+import dagger.mapkeys.ClassKey;
+import dagger.mapkeys.StringKey;
+
+@MapKey(unwrapValue = false)
+@interface WrappedAnnotationKey {
+  StringKey value();
+  int[] integers();
+  ClassKey[] annotations();
+  Class<? extends Number>[] classes();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/ByteModule.java b/compiler/src/it/functional-tests/src/main/java/test/builder/ByteModule.java
new file mode 100644
index 0000000..8b85d60
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/ByteModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class ByteModule {
+  final byte b;
+
+  ByteModule(byte b) {
+    this.b = b;
+  }
+  
+  @Provides byte b() { return b; }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/DepComponent.java b/compiler/src/it/functional-tests/src/main/java/test/builder/DepComponent.java
new file mode 100644
index 0000000..93fd59d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/DepComponent.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+
+@Component
+interface DepComponent {
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/DoubleModule.java b/compiler/src/it/functional-tests/src/main/java/test/builder/DoubleModule.java
new file mode 100644
index 0000000..2dec4a7
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/DoubleModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class DoubleModule {
+  @Provides
+  double d() {
+    return 4.2d;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/FloatModule.java b/compiler/src/it/functional-tests/src/main/java/test/builder/FloatModule.java
new file mode 100644
index 0000000..309e7ee
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/FloatModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class FloatModule {  
+  @Provides
+  float f() {
+    return 5.5f;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/GenericParent.java b/compiler/src/it/functional-tests/src/main/java/test/builder/GenericParent.java
new file mode 100644
index 0000000..af196ee
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/GenericParent.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+interface GenericParent<B> {  
+  B subcomponentBuilder();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/Grandchild.java b/compiler/src/it/functional-tests/src/main/java/test/builder/Grandchild.java
new file mode 100644
index 0000000..8cbf67b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/Grandchild.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = IntModuleIncludingDoubleAndFloat.class)
+interface Grandchild {
+  int i();
+  String s();
+
+  @Subcomponent.Builder
+  interface Builder {
+    Grandchild build();
+    Builder set(IntModuleIncludingDoubleAndFloat intModule);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/IntModuleIncludingDoubleAndFloat.java b/compiler/src/it/functional-tests/src/main/java/test/builder/IntModuleIncludingDoubleAndFloat.java
new file mode 100644
index 0000000..5e3a928
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/IntModuleIncludingDoubleAndFloat.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module(includes = { DoubleModule.class, FloatModule.class })
+class IntModuleIncludingDoubleAndFloat {
+  final int integer;
+
+  IntModuleIncludingDoubleAndFloat(int integer) {
+    this.integer = integer;
+  }
+  
+  @Provides
+  int integer() {
+    return integer;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/LongModule.java b/compiler/src/it/functional-tests/src/main/java/test/builder/LongModule.java
new file mode 100644
index 0000000..c16c9c7
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/LongModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class LongModule {  
+  @Provides
+  long l() {
+    return 6L;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleChild.java b/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleChild.java
new file mode 100644
index 0000000..690c91a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleChild.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Subcomponent;
+
+@MiddleScope
+@Subcomponent(modules = StringModule.class)
+interface MiddleChild {
+  String s();
+  
+  Grandchild.Builder grandchildBuilder();
+  
+  RequiresSubcomponentBuilder<Grandchild.Builder> requiresGrandchildBuilder();
+  
+  @Subcomponent.Builder
+  interface Builder {
+    MiddleChild build();
+    Builder set(StringModule stringModule);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleScope.java b/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleScope.java
new file mode 100644
index 0000000..e2fbcaa
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/MiddleScope.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import java.lang.annotation.Retention;
+import javax.inject.Scope;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Scope
+@Retention(RUNTIME)
+@interface MiddleScope {
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/OtherMiddleChild.java b/compiler/src/it/functional-tests/src/main/java/test/builder/OtherMiddleChild.java
new file mode 100644
index 0000000..28e43ba
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/OtherMiddleChild.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Subcomponent;
+
+@MiddleScope
+@Subcomponent(modules = {StringModule.class, LongModule.class})
+interface OtherMiddleChild {
+  long l();
+  String s();
+  
+  Grandchild.Builder grandchildBuilder();
+  
+  @Subcomponent.Builder
+  interface Builder {
+    OtherMiddleChild build();
+    Builder set(StringModule stringModule);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/ParentComponent.java b/compiler/src/it/functional-tests/src/main/java/test/builder/ParentComponent.java
new file mode 100644
index 0000000..584eff6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/ParentComponent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Singleton
+@Component
+interface ParentComponent {  
+  TestChildComponentWithBuilderAbstractClass.Builder childAbstractClassBuilder();
+  TestChildComponentWithBuilderInterface.Builder childInterfaceBuilder();
+  
+  MiddleChild.Builder middleBuilder();
+  OtherMiddleChild.Builder otherBuilder();
+  
+  RequiresSubcomponentBuilder<MiddleChild.Builder> requiresMiddleChildBuilder();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/ParentOfGenericComponent.java b/compiler/src/it/functional-tests/src/main/java/test/builder/ParentOfGenericComponent.java
new file mode 100644
index 0000000..474c617
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/ParentOfGenericComponent.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Component(modules = StringModule.class)
+@Singleton
+interface ParentOfGenericComponent extends GenericParent<Grandchild.Builder> {}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/RequiresSubcomponentBuilder.java b/compiler/src/it/functional-tests/src/main/java/test/builder/RequiresSubcomponentBuilder.java
new file mode 100644
index 0000000..ee99632
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/RequiresSubcomponentBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+class RequiresSubcomponentBuilder<B> {
+  private final Provider<B> subcomponentBuilderProvider;
+  private final B subcomponentBuilder;
+
+  @Inject
+  RequiresSubcomponentBuilder(Provider<B> subcomponentBuilderProvider, B subcomponentBuilder) {
+    this.subcomponentBuilderProvider = subcomponentBuilderProvider;
+    this.subcomponentBuilder = subcomponentBuilder;
+  }
+
+  Provider<B> subcomponentBuilderProvider() {
+    return subcomponentBuilderProvider;
+  }
+  
+  B subcomponentBuilder() {
+    return subcomponentBuilder;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/StringModule.java b/compiler/src/it/functional-tests/src/main/java/test/builder/StringModule.java
new file mode 100644
index 0000000..3b979a5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/StringModule.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class StringModule {
+  final String string;
+
+  StringModule(String string) {
+    this.string = string;
+  }
+  
+  @Provides
+  String string() {
+    return string;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderAbstractClass.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderAbstractClass.java
new file mode 100644
index 0000000..8f39c14
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderAbstractClass.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class,
+    LongModule.class, ByteModule.class})
+interface TestChildComponentWithBuilderAbstractClass {
+  String s();
+  int i();
+  long l();
+  float f();
+  double d();
+  byte b();
+ 
+  abstract class SharedBuilder<B, C, M1, M2> {
+    abstract C build(); // Test resolving return type of build()
+    abstract B setM1(M1 m1); // Test resolving return type & param of setter
+    abstract SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
+    abstract void setM3(DoubleModule doubleModule);  // Test being overridden
+    abstract SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test returning supertype.
+  }
+  
+  @Subcomponent.Builder
+  abstract class Builder extends SharedBuilder<Builder, TestChildComponentWithBuilderAbstractClass,
+      StringModule, IntModuleIncludingDoubleAndFloat> {
+    @Override abstract Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariance
+    @Override abstract void setM3(DoubleModule doubleModule); // Test simple overrides allowed    
+    abstract void set(ByteModule byteModule);
+    
+    // Note we're missing LongModule -- it's implicit
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderInterface.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderInterface.java
new file mode 100644
index 0000000..2add34e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestChildComponentWithBuilderInterface.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class,
+    LongModule.class, ByteModule.class})
+interface TestChildComponentWithBuilderInterface {
+  String s();
+  int i();
+  long l();
+  float f();
+  double d();
+  byte b();
+  
+  interface SharedBuilder<B, C, M1, M2> {
+    C build(); // Test resolving return type of build()
+    B setM1(M1 m1); // Test resolving return type & param of setter
+    SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
+    void setM3(DoubleModule doubleModule);  // Test being overridden
+    SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test return type is supertype.
+  }
+  
+  @Subcomponent.Builder
+  interface Builder extends SharedBuilder<Builder, TestChildComponentWithBuilderInterface,
+      StringModule, IntModuleIncludingDoubleAndFloat> {
+    @Override Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides
+    @Override void setM3(DoubleModule doubleModule); // Test simple overrides allowed    
+    void set(ByteModule byteModule);
+    
+    // Note we're missing LongModule -- it's implicit
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderAbstractClass.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderAbstractClass.java
new file mode 100644
index 0000000..5eef53f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderAbstractClass.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+
+@Component(
+    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
+    dependencies = DepComponent.class)
+abstract class TestComponentWithBuilderAbstractClass {
+  
+  static Builder builder() {
+    return DaggerTestComponentWithBuilderAbstractClass.builder();
+  }
+  
+  abstract String s();
+  abstract int i();
+  abstract long l();
+  abstract float f();
+  abstract double d();
+  
+
+  static abstract class SharedBuilder {
+    // Make sure we use the overriding signature.
+    abstract Object build();
+    
+    Object stringModule(@SuppressWarnings("unused") StringModule stringModule) {
+      return null;
+    } 
+
+    SharedBuilder ignoredLongModule(@SuppressWarnings("unused") LongModule longModule) {
+      return null;
+    }
+    
+  }
+  
+  @Component.Builder
+  static abstract class Builder extends SharedBuilder {
+    @Override abstract TestComponentWithBuilderAbstractClass build(); // Narrowing return type
+    @Override abstract Builder stringModule(StringModule stringModule); // Make abstract & narrow
+    abstract Builder intModule(IntModuleIncludingDoubleAndFloat intModule);
+    abstract void doubleModule(DoubleModule doubleModule); // Module w/o args
+    abstract void depComponent(DepComponent depComponent);
+
+    Builder ignoredIntModule(
+        @SuppressWarnings("unused") IntModuleIncludingDoubleAndFloat intModule) {
+      return null;
+    }    
+    
+    // Note we're missing LongModule & FloatModule -- they/re implicit
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderInterface.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderInterface.java
new file mode 100644
index 0000000..55214f8
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithBuilderInterface.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+
+@Component(
+    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
+    dependencies = DepComponent.class)
+interface TestComponentWithBuilderInterface {
+  String s();
+  int i();
+  long l();
+  float f();
+  double d();
+  
+  interface SharedBuilder {
+    // Make sure we use the overriding signature.
+    Object build();
+    Object stringModule(StringModule m1); 
+  }
+  
+  @Component.Builder
+  interface Builder extends SharedBuilder {
+    @Override TestComponentWithBuilderInterface build(); // Narrowing return type
+    @Override Builder stringModule(StringModule stringModule); // Narrowing return type
+    Builder intModule(IntModuleIncludingDoubleAndFloat intModule);
+    void doubleModule(DoubleModule doubleModule); // Module w/o args
+    void depComponent(DepComponent depComponent);
+    
+    // Note we're missing LongModule & FloatModule -- they/re implicit
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderAbstractClass.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderAbstractClass.java
new file mode 100644
index 0000000..8032185
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderAbstractClass.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+
+@Component(
+    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
+    dependencies = DepComponent.class)
+interface TestComponentWithGenericBuilderAbstractClass {
+  String s();
+  int i();
+  long l();
+  float f();
+  double d();
+  
+  static abstract class SharedBuilder<B, C, M1, M2> {
+    abstract C build(); // Test resolving return type of build()
+    abstract B setM1(M1 m1); // Test resolving return type & param of setter
+    abstract SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
+    abstract void doubleModule(DoubleModule doubleModule);  // Test being overridden
+    abstract SharedBuilder<B, C, M1, M2> depComponent(FloatModule floatModule); // Test return type
+  }
+  
+  @Component.Builder
+  static abstract class Builder extends SharedBuilder<Builder,
+      TestComponentWithGenericBuilderAbstractClass, StringModule,
+      IntModuleIncludingDoubleAndFloat> {
+    @Override abstract Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides
+    @Override abstract void doubleModule(DoubleModule module3); // Test simple overrides allowed    
+    abstract void depComponent(DepComponent depComponent);
+    
+    // Note we're missing LongModule & FloatModule -- they're implicit
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderInterface.java b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderInterface.java
new file mode 100644
index 0000000..f63e3ec
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/builder/TestComponentWithGenericBuilderInterface.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import dagger.Component;
+
+@Component(
+    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
+    dependencies = DepComponent.class)
+interface TestComponentWithGenericBuilderInterface {
+  String s();
+  int i();
+  long l();
+  float f();
+  double d();
+  
+  interface SharedBuilder<B, C, M1, M2> {
+    C build(); // Test resolving return type of build()
+    B setM1(M1 m1); // Test resolving return type & param of setter
+    SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
+    void doubleModule(DoubleModule doubleModule);  // Test being overridden
+    SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test return type is supertype.
+  }
+  
+  @Component.Builder
+  interface Builder extends SharedBuilder<Builder, TestComponentWithGenericBuilderInterface,
+      StringModule, IntModuleIncludingDoubleAndFloat> {
+    @Override Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides allowed
+    @Override void doubleModule(DoubleModule module3); // Test simple overrides allowed    
+    void depComponent(DepComponent depComponent);
+    
+    // Note we're missing M5 -- that's implicit.
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/cycle/Cycles.java b/compiler/src/it/functional-tests/src/main/java/test/cycle/Cycles.java
new file mode 100644
index 0000000..8d67d92
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/cycle/Cycles.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.cycle;
+
+import dagger.Component;
+import dagger.Lazy;
+import dagger.Module;
+import dagger.Provides;
+import dagger.Subcomponent;
+import dagger.mapkeys.StringKey;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import static dagger.Provides.Type.MAP;
+
+/**
+ * Cycle classes used for testing cyclic dependencies.
+ * A <- (E <- D <- B <- C <- Provider<A>, Lazy<A>), (B <- C <- Provider<A>, Lazy<A>)
+ * S <- Provider<S>, Lazy<S>
+ *
+ * @author Tony Bentancur
+ * @since 2.0
+ */
+
+final class Cycles {
+  private Cycles() {}
+
+  static class A {
+    public final B b;
+    public final E e;
+
+    @Inject
+    A(E e, B b) {
+      this.e = e;
+      this.b = b;
+    }
+  }
+
+  static class B {
+    public final C c;
+
+    @Inject
+    B(C c) {
+      this.c = c;
+    }
+  }
+
+  static class C {
+    public final Provider<A> aProvider;
+    @Inject public Lazy<A> aLazy;
+
+    @Inject
+    C(Provider<A> aProvider) {
+      this.aProvider = aProvider;
+    }
+  }
+
+  static class D {
+    public final B b;
+
+    @Inject
+    D(B b) {
+      this.b = b;
+    }
+  }
+
+  static class E {
+    public final D d;
+
+    @Inject
+    E(D d) {
+      this.d = d;
+    }
+  }
+
+  static class S {
+    public final Provider<S> sProvider;
+    @Inject public Lazy<S> sLazy;
+
+    @Inject
+    S(Provider<S> sProvider) {
+      this.sProvider = sProvider;
+    }
+  }
+
+  static class X {
+    public final Y y;
+
+    @Inject
+    X(Y y) {
+      this.y = y;
+    }
+  }
+
+  static class Y {
+    public final Map<String, Provider<X>> mapOfProvidersOfX;
+    public final Map<String, Provider<Y>> mapOfProvidersOfY;
+
+    @Inject
+    Y(Map<String, Provider<X>> mapOfProvidersOfX, Map<String, Provider<Y>> mapOfProvidersOfY) {
+      this.mapOfProvidersOfX = mapOfProvidersOfX;
+      this.mapOfProvidersOfY = mapOfProvidersOfY;
+    }
+  }
+
+  @Module
+  static class CycleMapModule {
+    @Provides(type = MAP)
+    @StringKey("X")
+    static X x(X x) {
+      return x;
+    }
+
+    @Provides(type = MAP)
+    @StringKey("Y")
+    static Y y(Y y) {
+      return y;
+    }
+  }
+
+  @SuppressWarnings("dependency-cycle")
+  @Component(modules = CycleMapModule.class)
+  interface CycleMapComponent {
+    Y y();
+  }
+
+  @SuppressWarnings("dependency-cycle")
+  @Component
+  interface CycleComponent {
+    A a();
+
+    C c();
+
+    ChildCycleComponent child();
+  }
+
+  @SuppressWarnings("dependency-cycle")
+  @Component
+  interface SelfCycleComponent {
+    S s();
+  }
+
+  @Subcomponent
+  interface ChildCycleComponent {
+    @SuppressWarnings("dependency-cycle")
+    A a();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/cycle/LongCycle.java b/compiler/src/it/functional-tests/src/main/java/test/cycle/LongCycle.java
new file mode 100644
index 0000000..b4f61e0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/cycle/LongCycle.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.cycle;
+
+import dagger.Component;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+final class LongCycle {
+  static class Class1 { @Inject Class1(Class2 class2) {} }
+  static class Class2 { @Inject Class2(Class3 class3) {} }
+  static class Class3 { @Inject Class3(Class4 class4) {} }
+  static class Class4 { @Inject Class4(Class5 class5) {} }
+  static class Class5 { @Inject Class5(Class6 class6) {} }
+  static class Class6 { @Inject Class6(Class7 class7) {} }
+  static class Class7 { @Inject Class7(Class8 class8) {} }
+  static class Class8 { @Inject Class8(Class9 class9) {} }
+  static class Class9 { @Inject Class9(Class10 class10) {} }
+  static class Class10 { @Inject Class10(Class11 class11) {} }
+  static class Class11 { @Inject Class11(Class12 class12) {} }
+  static class Class12 { @Inject Class12(Class13 class13) {} }
+  static class Class13 { @Inject Class13(Class14 class14) {} }
+  static class Class14 { @Inject Class14(Class15 class15) {} }
+  static class Class15 { @Inject Class15(Class16 class16) {} }
+  static class Class16 { @Inject Class16(Class17 class17) {} }
+  static class Class17 { @Inject Class17(Class18 class18) {} }
+  static class Class18 { @Inject Class18(Class19 class19) {} }
+  static class Class19 { @Inject Class19(Class20 class20) {} }
+  static class Class20 { @Inject Class20(Class21 class21) {} }
+  static class Class21 { @Inject Class21(Class22 class22) {} }
+  static class Class22 { @Inject Class22(Class23 class23) {} }
+  static class Class23 { @Inject Class23(Class24 class24) {} }
+  static class Class24 { @Inject Class24(Class25 class25) {} }
+  static class Class25 { @Inject Class25(Class26 class26) {} }
+  static class Class26 { @Inject Class26(Class27 class27) {} }
+  static class Class27 { @Inject Class27(Class28 class28) {} }
+  static class Class28 { @Inject Class28(Class29 class29) {} }
+  static class Class29 { @Inject Class29(Class30 class30) {} }
+  static class Class30 { @Inject Class30(Class31 class31) {} }
+  static class Class31 { @Inject Class31(Class32 class32) {} }
+  static class Class32 { @Inject Class32(Class33 class33) {} }
+  static class Class33 { @Inject Class33(Class34 class34) {} }
+  static class Class34 { @Inject Class34(Class35 class35) {} }
+  static class Class35 { @Inject Class35(Class36 class36) {} }
+  static class Class36 { @Inject Class36(Class37 class37) {} }
+  static class Class37 { @Inject Class37(Class38 class38) {} }
+  static class Class38 { @Inject Class38(Class39 class39) {} }
+  static class Class39 { @Inject Class39(Class40 class40) {} }
+  static class Class40 { @Inject Class40(Class41 class41) {} }
+  static class Class41 { @Inject Class41(Class42 class42) {} }
+  static class Class42 { @Inject Class42(Class43 class43) {} }
+  static class Class43 { @Inject Class43(Class44 class44) {} }
+  static class Class44 { @Inject Class44(Class45 class45) {} }
+  static class Class45 { @Inject Class45(Class46 class46) {} }
+  static class Class46 { @Inject Class46(Class47 class47) {} }
+  static class Class47 { @Inject Class47(Class48 class48) {} }
+  static class Class48 { @Inject Class48(Class49 class49) {} }
+  static class Class49 { @Inject Class49(Class50 class50) {} }
+  static class Class50 { @Inject Class50(Class51 class51) {} }
+  static class Class51 { @Inject Class51(Class52 class52) {} }
+  static class Class52 { @Inject Class52(Class53 class53) {} }
+  static class Class53 { @Inject Class53(Class54 class54) {} }
+  static class Class54 { @Inject Class54(Class55 class55) {} }
+  static class Class55 { @Inject Class55(Class56 class56) {} }
+  static class Class56 { @Inject Class56(Class57 class57) {} }
+  static class Class57 { @Inject Class57(Class58 class58) {} }
+  static class Class58 { @Inject Class58(Class59 class59) {} }
+  static class Class59 { @Inject Class59(Class60 class60) {} }
+  static class Class60 { @Inject Class60(Class61 class61) {} }
+  static class Class61 { @Inject Class61(Class62 class62) {} }
+  static class Class62 { @Inject Class62(Class63 class63) {} }
+  static class Class63 { @Inject Class63(Class64 class64) {} }
+  static class Class64 { @Inject Class64(Class65 class65) {} }
+  static class Class65 { @Inject Class65(Class66 class66) {} }
+  static class Class66 { @Inject Class66(Class67 class67) {} }
+  static class Class67 { @Inject Class67(Class68 class68) {} }
+  static class Class68 { @Inject Class68(Class69 class69) {} }
+  static class Class69 { @Inject Class69(Class70 class70) {} }
+  static class Class70 { @Inject Class70(Class71 class71) {} }
+  static class Class71 { @Inject Class71(Class72 class72) {} }
+  static class Class72 { @Inject Class72(Class73 class73) {} }
+  static class Class73 { @Inject Class73(Class74 class74) {} }
+  static class Class74 { @Inject Class74(Class75 class75) {} }
+  static class Class75 { @Inject Class75(Class76 class76) {} }
+  static class Class76 { @Inject Class76(Class77 class77) {} }
+  static class Class77 { @Inject Class77(Class78 class78) {} }
+  static class Class78 { @Inject Class78(Class79 class79) {} }
+  static class Class79 { @Inject Class79(Class80 class80) {} }
+  static class Class80 { @Inject Class80(Class81 class81) {} }
+  static class Class81 { @Inject Class81(Class82 class82) {} }
+  static class Class82 { @Inject Class82(Class83 class83) {} }
+  static class Class83 { @Inject Class83(Class84 class84) {} }
+  static class Class84 { @Inject Class84(Class85 class85) {} }
+  static class Class85 { @Inject Class85(Class86 class86) {} }
+  static class Class86 { @Inject Class86(Class87 class87) {} }
+  static class Class87 { @Inject Class87(Class88 class88) {} }
+  static class Class88 { @Inject Class88(Class89 class89) {} }
+  static class Class89 { @Inject Class89(Class90 class90) {} }
+  static class Class90 { @Inject Class90(Class91 class91) {} }
+  static class Class91 { @Inject Class91(Class92 class92) {} }
+  static class Class92 { @Inject Class92(Class93 class93) {} }
+  static class Class93 { @Inject Class93(Class94 class94) {} }
+  static class Class94 { @Inject Class94(Class95 class95) {} }
+  static class Class95 { @Inject Class95(Class96 class96) {} }
+  static class Class96 { @Inject Class96(Class97 class97) {} }
+  static class Class97 { @Inject Class97(Class98 class98) {} }
+  static class Class98 { @Inject Class98(Class99 class99) {} }
+  static class Class99 { @Inject Class99(Class100 class100) {} }
+  static class Class100 { @Inject Class100(Class101 class101) {} }
+  static class Class101 { @Inject Class101(Provider<Class1> class1Provider) {} }
+
+  @SuppressWarnings("dependency-cycle")
+  @Component
+  interface LongCycleComponent {
+    Class1 class1();
+  }
+
+  private LongCycle() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfArrayOfParentOfStringArray.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfArrayOfParentOfStringArray.java
new file mode 100644
index 0000000..22efcf1
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfArrayOfParentOfStringArray.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+class ChildOfArrayOfParentOfStringArray extends
+    MembersInjectGenericParent<MembersInjectGenericParent<String[]>[]> {
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfPrimitiveIntArray.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfPrimitiveIntArray.java
new file mode 100644
index 0000000..e01c1c2
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfPrimitiveIntArray.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+class ChildOfPrimitiveIntArray extends MembersInjectGenericParent<int[]> {
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfStringArray.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfStringArray.java
new file mode 100644
index 0000000..8ec943b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/ChildOfStringArray.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+class ChildOfStringArray extends MembersInjectGenericParent<String[]> {
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectComponent.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectComponent.java
new file mode 100644
index 0000000..9ab8c19
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectComponent.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+import dagger.Component;
+
+@Component(modules = {MembersInjectModule.class})
+interface MembersInjectComponent {
+  
+  void inject(ChildOfStringArray subfoo);
+  void inject(ChildOfArrayOfParentOfStringArray subfoo);
+  void inject(ChildOfPrimitiveIntArray subfoo);
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectGenericParent.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectGenericParent.java
new file mode 100644
index 0000000..064b886
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectGenericParent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+import javax.inject.Inject;
+
+class MembersInjectGenericParent<T> {
+  
+  @Inject T t; 
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectModule.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectModule.java
new file mode 100644
index 0000000..a6c1fad
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/MembersInjectModule.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class MembersInjectModule {
+  
+  @Provides String[] provideStringArray() { return new String[10]; }
+  
+  @Provides int[] provideIntArray() { return new int[10]; }
+  
+  @SuppressWarnings("unchecked")
+  @Provides MembersInjectGenericParent<String[]>[] provideFooArrayOfStringArray() { return new MembersInjectGenericParent[10]; }
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/membersinject/NonRequestedChild.java b/compiler/src/it/functional-tests/src/main/java/test/membersinject/NonRequestedChild.java
new file mode 100644
index 0000000..108a1b5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/membersinject/NonRequestedChild.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+import javax.inject.Inject;
+
+/**
+ * A class that should not be requested by any component, to ensure that we still generate a members
+ * injector for it.
+ */
+class NonRequestedChild extends MembersInjectGenericParent<String> {
+  @Inject
+  NonRequestedChild() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/FooComponent.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/FooComponent.java
new file mode 100644
index 0000000..3c88415
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/FooComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage;
+
+import dagger.Component;
+import java.util.Set;
+import test.multipackage.a.AModule;
+import test.multipackage.sub.FooChildComponent;
+
+/**
+ * A component that tests the interaction between subcomponents, multiple packages, and
+ * multibindings. Specifically, we want:
+ * <ul>
+ * <li>A set binding with some contributions in the parent component, and some in the subcomponent.
+ * <li>The contributions come from different packages, but not the package of either component.
+ * <li>The set binding is requested in the subcomponent through a binding from a separate package.
+ * <li>No binding in the subcomponent, that's in the subcomponent's package, directly uses any
+ *     binding from the component's package.
+ * </ul>
+ */
+// NOTE(beder): Be careful about changing any bindings in either this component or the subcomponent.
+// Even adding a binding might stop this test from testing what it's supposed to test.
+@Component(modules = {AModule.class})
+interface FooComponent {
+  Set<String> setOfString();
+
+  FooChildComponent fooChildComponent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/MembersInjectionVisibilityComponent.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/MembersInjectionVisibilityComponent.java
new file mode 100644
index 0000000..85ce40a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/MembersInjectionVisibilityComponent.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage;
+
+import dagger.Component;
+import test.multipackage.a.AGrandchild;
+import test.multipackage.a.AModule;
+import test.multipackage.a.AParent;
+import test.multipackage.b.BChild;
+
+/**
+ * A component that tests members injection across packages and subclasses.
+ */
+@Component(modules = {AModule.class})
+public interface MembersInjectionVisibilityComponent {
+  void inject(AParent aParent);
+
+  void inject(BChild aChild);
+
+  void inject(AGrandchild aGrandchild);
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AGrandchild.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AGrandchild.java
new file mode 100644
index 0000000..8f0f1f3
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AGrandchild.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.a;
+
+import javax.inject.Inject;
+import test.multipackage.b.BChild;
+
+public class AGrandchild extends BChild {
+
+  @Inject APackagePrivateObject aGrandchildField;
+
+  private APackagePrivateObject aGrandchildMethod;
+
+  @Inject
+  void aGrandchildMethod(APackagePrivateObject aGrandchildMethod) {
+    this.aGrandchildMethod = aGrandchildMethod;
+  }
+
+  @Override
+  @Inject
+  protected void aParentMethod(APublicObject aParentMethod) {
+    super.aParentMethod(aParentMethod);
+  }
+
+  @Override
+  protected void aChildMethod(APublicObject aChildMethod) {
+    super.aChildMethod(aChildMethod);
+  }
+
+  public APackagePrivateObject aGrandchildField() {
+    return aGrandchildField;
+  }
+
+  public APackagePrivateObject aGrandchildMethod() {
+    return aGrandchildMethod;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AModule.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AModule.java
new file mode 100644
index 0000000..d62506a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AModule.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.a;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+public final class AModule {
+  @Provides(type = SET) String provideString() {
+    return "a";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APackagePrivateObject.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APackagePrivateObject.java
new file mode 100644
index 0000000..d604133
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APackagePrivateObject.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.a;
+
+import javax.inject.Inject;
+
+class APackagePrivateObject {
+
+  @Inject
+  APackagePrivateObject() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AParent.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AParent.java
new file mode 100644
index 0000000..4c91a6f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/AParent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.a;
+
+import javax.inject.Inject;
+
+public class AParent {
+
+  @Inject APackagePrivateObject aParentField;
+
+  private APublicObject aParentMethod;
+
+  @Inject
+  protected void aParentMethod(APublicObject aParentMethod) {
+    this.aParentMethod = aParentMethod;
+  }
+
+  public APackagePrivateObject aParentField() {
+    return aParentField;
+  }
+
+  public APublicObject aParentMethod() {
+    return aParentMethod;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APublicObject.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APublicObject.java
new file mode 100644
index 0000000..90357f6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/a/APublicObject.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.a;
+
+import javax.inject.Inject;
+
+public class APublicObject {
+
+  @Inject
+  APublicObject() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BChild.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BChild.java
new file mode 100644
index 0000000..188d120
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BChild.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.b;
+
+import javax.inject.Inject;
+import test.multipackage.a.AParent;
+import test.multipackage.a.APublicObject;
+
+public class BChild extends AParent {
+
+  @Inject BPackagePrivateObject aChildField;
+
+  private APublicObject aChildMethod;
+
+  @Inject
+  protected void aChildMethod(APublicObject aChildMethod) {
+    this.aChildMethod = aChildMethod;
+  }
+
+  @Override
+  protected void aParentMethod(APublicObject aParentMethod) {
+    super.aParentMethod(aParentMethod);
+  }
+
+  public BPackagePrivateObject aChildField() {
+    return aChildField;
+  }
+
+  public APublicObject aChildMethod() {
+    return aChildMethod;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BModule.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BModule.java
new file mode 100644
index 0000000..4d817f1
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BModule.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.b;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+public final class BModule {
+  @Provides(type = SET) String provideString() {
+    return "b";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BPackagePrivateObject.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BPackagePrivateObject.java
new file mode 100644
index 0000000..c397a02
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/b/BPackagePrivateObject.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.b;
+
+import javax.inject.Inject;
+
+class BPackagePrivateObject {
+
+  @Inject
+  BPackagePrivateObject() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/c/CModule.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/c/CModule.java
new file mode 100644
index 0000000..e608afb
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/c/CModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.c;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.Set;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+public final class CModule {
+  @Provides(type = SET) String provideString() {
+    return "c";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/d/DModule.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/d/DModule.java
new file mode 100644
index 0000000..51f8ace
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/d/DModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.d;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.Set;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+public final class DModule {
+  @Provides(type = SET) String provideString() {
+    return "d";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/foo/Foo.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/foo/Foo.java
new file mode 100644
index 0000000..35f5862
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/foo/Foo.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.foo;
+
+import java.util.Set;
+import javax.inject.Inject;
+
+public final class Foo<T> {
+  public final Set<String> strings;
+
+  @Inject Foo(Set<String> strings) {
+    this.strings = strings;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/grandsub/FooGrandchildComponent.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/grandsub/FooGrandchildComponent.java
new file mode 100644
index 0000000..16a61dd
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/grandsub/FooGrandchildComponent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.grandsub;
+
+import dagger.Subcomponent;
+import test.multipackage.d.DModule;
+import test.multipackage.foo.Foo;
+
+@Subcomponent(modules = DModule.class)
+public interface FooGrandchildComponent {
+  Foo<FooGrandchildComponent> foo();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/multipackage/sub/FooChildComponent.java b/compiler/src/it/functional-tests/src/main/java/test/multipackage/sub/FooChildComponent.java
new file mode 100644
index 0000000..9050fcd
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/multipackage/sub/FooChildComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.multipackage.sub;
+
+import dagger.Subcomponent;
+import test.multipackage.b.BModule;
+import test.multipackage.c.CModule;
+import test.multipackage.foo.Foo;
+import test.multipackage.grandsub.FooGrandchildComponent;
+
+@Subcomponent(modules = {BModule.class, CModule.class})
+public interface FooChildComponent {
+  Foo<FooChildComponent> foo();
+
+  FooGrandchildComponent fooGrandchildComponent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponent.java b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponent.java
new file mode 100644
index 0000000..a8a5724
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponent.java
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test.nullables;
+
+import javax.inject.Provider;
+
+import dagger.Component;
+
+@Component(modules = NullModule.class)
+interface NullComponent {
+  NullFoo nullFoo();
+  @Nullable String string();
+  Provider<String> stringProvider();
+  Number number();
+  Provider<Number> numberProvider();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponentWithDependency.java b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponentWithDependency.java
new file mode 100644
index 0000000..05093ed
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullComponentWithDependency.java
@@ -0,0 +1,28 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test.nullables;
+
+import javax.inject.Provider;
+
+import dagger.Component;
+
+@Component(dependencies = NullComponent.class)
+interface NullComponentWithDependency {
+  @Nullable String string();
+  Provider<String> stringProvider();
+  Number number();
+  Provider<Number> numberProvider();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/nullables/NullFoo.java b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullFoo.java
new file mode 100644
index 0000000..9ed4b5d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullFoo.java
@@ -0,0 +1,56 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test.nullables;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+class NullFoo {
+  final String string;
+  final Provider<String> stringProvider;
+  final Number number;
+  final Provider<Number> numberProvider;
+
+  @Inject
+  NullFoo(@Nullable String string,
+      Provider<String> stringProvider,
+      Number number,
+      Provider<Number> numberProvider) {
+    this.string = string;
+    this.stringProvider = stringProvider;
+    this.number = number;
+    this.numberProvider = numberProvider;
+  }
+
+  String methodInjectedString;
+  Provider<String> methodInjectedStringProvider;
+  Number methodInjectedNumber;
+  Provider<Number> methodInjectedNumberProvider;
+  @Inject void inject(@Nullable String string,
+      Provider<String> stringProvider,
+      Number number,
+      Provider<Number> numberProvider) {
+    this.methodInjectedString = string;
+    this.methodInjectedStringProvider = stringProvider;
+    this.methodInjectedNumber = number;
+    this.methodInjectedNumberProvider = numberProvider;
+  }
+
+  @Nullable @Inject String fieldInjectedString;
+  @Inject Provider<String> fieldInjectedStringProvider;
+  @Inject Number fieldInjectedNumber;
+  @Inject Provider<Number> fieldInjectedNumberProvider;
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/nullables/NullModule.java b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullModule.java
new file mode 100644
index 0000000..652d5eb
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/nullables/NullModule.java
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test.nullables;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+class NullModule {
+  Number numberValue = null;
+
+  @Nullable
+  @Provides
+  String provideNullableString() {
+    return null;
+  }
+
+  @Provides
+  Number provideNumber() {
+    return numberValue;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/nullables/Nullable.java b/compiler/src/it/functional-tests/src/main/java/test/nullables/Nullable.java
new file mode 100644
index 0000000..8677640
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/nullables/Nullable.java
@@ -0,0 +1,3 @@
+package test.nullables;
+
+@interface Nullable {}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/staticprovides/AllStaticModule.java b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/AllStaticModule.java
new file mode 100644
index 0000000..f47d36c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/AllStaticModule.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.staticprovides;
+
+import static dagger.Provides.Type.SET;
+import static dagger.Provides.Type.SET_VALUES;
+import static java.util.Collections.emptySet;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.Set;
+
+@Module
+final class AllStaticModule {
+  @Provides(type = SET) static String contributeString() {
+    return AllStaticModule.class + ".contributeString";
+  }
+
+  @Provides(type = SET_VALUES) static Set<Integer> contibuteEmptyIntegerSet() {
+    return emptySet();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/staticprovides/SomeStaticModule.java b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/SomeStaticModule.java
new file mode 100644
index 0000000..53ee14d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/SomeStaticModule.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.staticprovides;
+
+import static dagger.Provides.Type.SET;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class SomeStaticModule {
+  @Provides(type = SET) static String contributeStringFromAStaticMethod() {
+    return SomeStaticModule.class + ".contributeStringFromAStaticMethod";
+  }
+
+  @Provides(type = SET) String contributeStringFromAnInstanceMethod() {
+    return SomeStaticModule.class + ".contributeStringFromAnInstanceMethod";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponent.java b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponent.java
new file mode 100644
index 0000000..4be51ed
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponent.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.staticprovides;
+
+import dagger.Component;
+import java.util.Set;
+
+/**
+ * A simple component that demonstrates both static and non-static provides methods.
+ */
+@Component(modules = {AllStaticModule.class, SomeStaticModule.class})
+interface StaticTestComponent {
+  Set<String> getMultiboundStrings();
+  Set<Integer> getMultiboundIntegers();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponentWithBuilder.java b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponentWithBuilder.java
new file mode 100644
index 0000000..d778fc5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/staticprovides/StaticTestComponentWithBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.staticprovides;
+
+import dagger.Component;
+
+/**
+ * A simple component that demonstrates both static and non-static provides methods with a builder.
+ */
+@Component(modules = {AllStaticModule.class, SomeStaticModule.class})
+interface StaticTestComponentWithBuilder extends StaticTestComponent {
+  @Component.Builder
+  interface Builder {
+    Builder allStaticModule(AllStaticModule allStaticModule);
+    Builder someStaticModule(SomeStaticModule someStaticModule);
+    StaticTestComponentWithBuilder build();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/ContributionsModule.java b/compiler/src/it/functional-tests/src/main/java/test/sub/ContributionsModule.java
new file mode 100644
index 0000000..b10ac45
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/ContributionsModule.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.sub;
+
+import dagger.Module;
+import dagger.Provides;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static dagger.Provides.Type.SET;
+import static dagger.Provides.Type.SET_VALUES;
+
+@Module
+public final class ContributionsModule {
+  @Provides(type = SET) int contributeAnInt(double doubleDependency) {
+    return 1742;
+  }
+
+  @Provides(type = SET) int contributeAnotherInt() {
+    return 832;
+  }
+
+  @Provides(type = SET_VALUES) Set<Integer> contributeSomeInts() {
+    return Collections.unmodifiableSet(new LinkedHashSet<Integer>(Arrays.asList(-1, -90, -17)));
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/Exposed.java b/compiler/src/it/functional-tests/src/main/java/test/sub/Exposed.java
new file mode 100644
index 0000000..9195b33
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/Exposed.java
@@ -0,0 +1,19 @@
+package test.sub;
+
+import javax.inject.Inject;
+import test.Generic;
+import test.Generic2;
+
+public class Exposed {
+  
+  @Inject public Generic2<PackagePrivate> gpp2;
+  @Inject public Generic2<PackagePrivateContainer.PublicEnclosed> gppc2;
+
+  public Generic<PackagePrivate> gpp;
+  public Generic<PackagePrivateContainer.PublicEnclosed> gppc;
+  
+  @Inject Exposed(Generic<PackagePrivate> gpp, Generic<PackagePrivateContainer.PublicEnclosed> gppc) {
+    this.gpp = gpp;
+    this.gppc = gppc;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/OtherThing.java b/compiler/src/it/functional-tests/src/main/java/test/sub/OtherThing.java
new file mode 100644
index 0000000..9493517
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/OtherThing.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.sub;
+
+import javax.inject.Inject;
+
+public final class OtherThing {
+  @Inject public OtherThing(int i) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivate.java b/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivate.java
new file mode 100644
index 0000000..9af646a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivate.java
@@ -0,0 +1,7 @@
+package test.sub;
+
+import javax.inject.Inject;
+
+class PackagePrivate {  
+  @Inject PackagePrivate() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivateContainer.java b/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivateContainer.java
new file mode 100644
index 0000000..765b015
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/PackagePrivateContainer.java
@@ -0,0 +1,9 @@
+package test.sub;
+
+import javax.inject.Inject;
+
+class PackagePrivateContainer {  
+  public static class PublicEnclosed {
+    @Inject PublicEnclosed() {}
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass.java b/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass.java
new file mode 100644
index 0000000..586d55d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass.java
@@ -0,0 +1,10 @@
+package test.sub;
+
+import javax.inject.Inject;
+import test.Generic;
+
+public class PublicSubclass extends Generic<PackagePrivate> {
+  @Inject public PublicSubclass(PackagePrivate pp) {
+    super(pp);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass2.java b/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass2.java
new file mode 100644
index 0000000..c356fa8
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/sub/PublicSubclass2.java
@@ -0,0 +1,10 @@
+package test.sub;
+
+import javax.inject.Inject;
+import test.Generic;
+
+public class PublicSubclass2 extends Generic<PackagePrivateContainer.PublicEnclosed> {
+  @Inject public PublicSubclass2(PackagePrivateContainer.PublicEnclosed pp) {
+    super(pp);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/AnInterface.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/AnInterface.java
new file mode 100644
index 0000000..8aaa015
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/AnInterface.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+interface AnInterface {
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/BoundAsSingleton.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/BoundAsSingleton.java
new file mode 100644
index 0000000..8ae1474
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/BoundAsSingleton.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Documented
+@Retention(RUNTIME)
+@Qualifier
+@interface BoundAsSingleton {}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildAbstractClassComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildAbstractClassComponent.java
new file mode 100644
index 0000000..2529433
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildAbstractClassComponent.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = {ChildModule.class, StaticChildModule.class})
+abstract class ChildAbstractClassComponent implements ChildComponent {
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponent.java
new file mode 100644
index 0000000..d3c28f2
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponent.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Subcomponent;
+import java.util.Set;
+import javax.inject.Provider;
+
+@Subcomponent(modules = {ChildModule.class, StaticChildModule.class})
+interface ChildComponent {
+  Provider<UnscopedType> getUnscopedTypeProvider();
+
+  RequiresSingletons requiresSingleton();
+
+  Set<Object> objectSet();
+
+  GrandchildComponent newGrandchildComponent();
+  
+  Object object();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentRequiringModules.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentRequiringModules.java
new file mode 100644
index 0000000..905c689
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentRequiringModules.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = {
+    ChildModule.class,
+    ChildModuleWithParameters.class,
+    ChildModuleWithState.class})
+interface ChildComponentRequiringModules {
+  int getInt();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentWithMultibindings.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentWithMultibindings.java
new file mode 100644
index 0000000..9ed266a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildComponentWithMultibindings.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = ChildMultibindingModule.class)
+interface ChildComponentWithMultibindings {
+  RequiresMultibindingsInChild requiresMultibindingsInChild();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModule.java
new file mode 100644
index 0000000..ef28bd4
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModule.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+final class ChildModule {
+  @Provides(type = SET) Object provideUnscopedObject() {
+    return new Object() {
+      @Override public String toString() {
+        return "unscoped in child";
+      }
+    };
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithParameters.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithParameters.java
new file mode 100644
index 0000000..e18b4a6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithParameters.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+
+/**
+ * This is a module that can't be constructed with a default constructor.
+ */
+@Module
+final class ChildModuleWithParameters {
+  public ChildModuleWithParameters(@SuppressWarnings("unused") Object whatever) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithState.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithState.java
new file mode 100644
index 0000000..5908a00
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildModuleWithState.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * This is a module that can be constructed with a default constructor, but has state, so callers
+ * might want to pass a reference anyway.
+ */
+@Module
+final class ChildModuleWithState {
+  private int i = 0;
+
+  @Provides int provideInt() {
+    return i++;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildMultibindingModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildMultibindingModule.java
new file mode 100644
index 0000000..ae02b9e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ChildMultibindingModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.mapkeys.StringKey;
+
+import static dagger.Provides.Type.MAP;
+import static dagger.Provides.Type.SET;
+
+@Module
+class ChildMultibindingModule {
+
+  @Provides(type = SET)
+  static Object childObject() {
+    return "object provided by child";
+  }
+
+  @Provides(type = MAP)
+  @StringKey("child key")
+  static Object childKeyObject() {
+    return "object in child";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GenericParentComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GenericParentComponent.java
new file mode 100644
index 0000000..5580ab8
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GenericParentComponent.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+interface GenericParentComponent<B> {  
+  B subcomponent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildComponent.java
new file mode 100644
index 0000000..9f724ed
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildComponent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Subcomponent;
+import java.util.Set;
+import javax.inject.Provider;
+
+@Subcomponent(modules = GrandchildModule.class)
+interface GrandchildComponent {
+  Provider<UnscopedType> getUnscopedTypeProvider();
+
+  RequiresSingletons requiresSingleton();
+
+  Set<Object> objectSet();
+
+  NeedsAnInterface needsAnInterface();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildModule.java
new file mode 100644
index 0000000..b288541
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/GrandchildModule.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+final class GrandchildModule {
+  @Provides(type = SET) Object provideUnscopedObject() {
+    return new Object() {
+      @Override public String toString() {
+        return "unscoped in grandchild";
+      }
+    };
+  }
+
+  @Provides AnInterface provideAnInterface(ImplementsAnInterface implementsAnInterface) {
+    return implementsAnInterface;
+  }
+
+  @Provides NeedsAnInterface provideNeedsAnInterface(AnInterface anInterface) {
+    return new NeedsAnInterface(anInterface);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ImplementsAnInterface.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ImplementsAnInterface.java
new file mode 100644
index 0000000..ff3170c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ImplementsAnInterface.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import javax.inject.Inject;
+
+class ImplementsAnInterface implements AnInterface {
+  @Inject ImplementsAnInterface() {}
+}
+
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/NeedsAnInterface.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/NeedsAnInterface.java
new file mode 100644
index 0000000..bccde85
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/NeedsAnInterface.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+class NeedsAnInterface {
+  NeedsAnInterface(AnInterface anInterface) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponent.java
new file mode 100644
index 0000000..ebb067d
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Component(modules = ParentModule.class)
+@Singleton
+interface ParentComponent extends ParentGetters {
+  ChildComponent newChildComponent();
+
+  ChildAbstractClassComponent newChildAbstractClassComponent();
+
+  ChildComponentRequiringModules newChildComponentRequiringModules(
+      ChildModuleWithParameters cmwp,
+      ChildModuleWithState childModuleWithState);
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithMultibindings.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithMultibindings.java
new file mode 100644
index 0000000..46fe883
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithMultibindings.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Component;
+
+@Component(modules = ParentMultibindingModule.class)
+interface ParentComponentWithMultibindings extends ParentComponentWithoutMultibindings {
+  RequiresMultibindingsInParent requiresMultibindingsInParent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithoutMultibindings.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithoutMultibindings.java
new file mode 100644
index 0000000..3d4431c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentComponentWithoutMultibindings.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Component;
+
+@Component(modules = ParentMultibindingModule.class)
+interface ParentComponentWithoutMultibindings {
+  ChildComponentWithMultibindings childComponent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentGetters.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentGetters.java
new file mode 100644
index 0000000..3ff855a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentGetters.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Set;
+import javax.inject.Provider;
+
+interface ParentGetters {
+  Provider<UnscopedType> getUnscopedTypeProvider();
+
+  Set<Object> objectSet();
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentModule.java
new file mode 100644
index 0000000..dbe1a53
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentModule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Singleton;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+final class ParentModule {
+  @Provides(type = SET) Object provideUnscopedObject() {
+    return new Object() {
+      @Override public String toString() {
+        return "unscoped in parent";
+      }
+    };
+  }
+
+  @Provides(type = SET) @Singleton Object provideSingletonObject() {
+    return new Object() {
+      @Override public String toString() {
+        return "singleton";
+      }
+    };
+  }
+
+  @Provides @Singleton @BoundAsSingleton UnscopedType provideUnscopedTypeBoundAsSingleton(
+      UnscopedType unscopedType) {
+    return unscopedType;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentMultibindingModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentMultibindingModule.java
new file mode 100644
index 0000000..e4ec173
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentMultibindingModule.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.mapkeys.StringKey;
+
+import static dagger.Provides.Type.MAP;
+import static dagger.Provides.Type.SET;
+
+@Module
+class ParentMultibindingModule {
+
+  @Provides(type = SET)
+  static Object provideObject() {
+    return "object provided by parent";
+  }
+
+  @Provides(type = SET)
+  static String provideString() {
+    return "string provided by parent";
+  }
+
+  @Provides(type = SET)
+  static RequiresMultiboundObjects requiresMultiboundObjects(
+      RequiresMultiboundObjects requiresMultiboundObjects) {
+    return requiresMultiboundObjects;
+  }
+
+  @Provides(type = MAP)
+  @StringKey("parent key")
+  static String parentKeyString() {
+    return "string in parent";
+  }
+
+  @Provides(type = MAP)
+  @StringKey("parent key")
+  static Object parentKeyObject() {
+    return "object in parent";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentOfGenericComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentOfGenericComponent.java
new file mode 100644
index 0000000..bf85537
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/ParentOfGenericComponent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Component(modules = ParentModule.class)
+@Singleton
+interface ParentOfGenericComponent extends GenericParentComponent<ChildComponent>, ParentGetters {
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInChild.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInChild.java
new file mode 100644
index 0000000..4ec0469
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInChild.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Set;
+import javax.inject.Inject;
+
+class RequiresMultibindingsInChild extends RequiresMultibindingsInParent {
+
+  @Inject
+  RequiresMultibindingsInChild(
+      RequiresMultiboundObjects requiresMultiboundObjects,
+      RequiresMultiboundStrings requiresMultiboundStrings,
+      Set<RequiresMultiboundObjects> setOfRequiresMultiboundObjects) {
+    super(requiresMultiboundObjects, requiresMultiboundStrings, setOfRequiresMultiboundObjects);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInParent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInParent.java
new file mode 100644
index 0000000..a48d38b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultibindingsInParent.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Set;
+import javax.inject.Inject;
+
+class RequiresMultibindingsInParent {
+  private final RequiresMultiboundObjects requiresMultiboundObjects;
+  private final RequiresMultiboundStrings requiresMultiboundStrings;
+  private final Set<RequiresMultiboundObjects> setOfRequiresMultiboundObjects;
+
+  @Inject
+  RequiresMultibindingsInParent(
+      RequiresMultiboundObjects requiresMultiboundObjects,
+      RequiresMultiboundStrings requiresMultiboundStrings,
+      Set<RequiresMultiboundObjects> setOfRequiresMultiboundObjects) {
+    this.requiresMultiboundObjects = requiresMultiboundObjects;
+    this.requiresMultiboundStrings = requiresMultiboundStrings;
+    this.setOfRequiresMultiboundObjects = setOfRequiresMultiboundObjects;
+  }
+
+  RequiresMultiboundObjects requiresMultiboundObjects() {
+    return requiresMultiboundObjects;
+  }
+
+  RequiresMultiboundStrings requiresMultiboundStrings() {
+    return requiresMultiboundStrings;
+  }
+
+  Set<RequiresMultiboundObjects> setOfRequiresMultiboundObjects() {
+    return setOfRequiresMultiboundObjects;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundObjects.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundObjects.java
new file mode 100644
index 0000000..d787153
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundObjects.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Inject;
+
+class RequiresMultiboundObjects {
+  private final Set<Object> setOfObjects;
+  private final Map<String, Object> mapOfObjects;
+
+  @Inject
+  RequiresMultiboundObjects(Set<Object> setOfObjects, Map<String, Object> mapOfObjects) {
+    this.setOfObjects = setOfObjects;
+    this.mapOfObjects = mapOfObjects;
+  }
+
+  Set<Object> setOfObjects() {
+    return setOfObjects;
+  }
+
+  Map<String, Object> mapOfObjects() {
+    return mapOfObjects;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundStrings.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundStrings.java
new file mode 100644
index 0000000..410bdf2
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresMultiboundStrings.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Inject;
+
+class RequiresMultiboundStrings {
+  private final Set<String> setOfStrings;
+  private final Map<String, String> mapOfStrings;
+
+  @Inject
+  RequiresMultiboundStrings(Set<String> setOfStrings, Map<String, String> mapOfStrings) {
+    this.setOfStrings = setOfStrings;
+    this.mapOfStrings = mapOfStrings;
+  }
+
+  Set<String> setOfStrings() {
+    return setOfStrings;
+  }
+
+  Map<String, String> mapOfStrings() {
+    return mapOfStrings;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresSingletons.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresSingletons.java
new file mode 100644
index 0000000..2d40538
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/RequiresSingletons.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import javax.inject.Inject;
+
+final class RequiresSingletons {
+  private final SingletonType singletonType;
+  private final UnscopedType unscopedTypeBoundAsSingleton;
+
+  @Inject RequiresSingletons(SingletonType singletonType,
+      @BoundAsSingleton UnscopedType unscopedTypeBoundAsSingleton) {
+    this.singletonType = singletonType;
+    this.unscopedTypeBoundAsSingleton = unscopedTypeBoundAsSingleton;
+  }
+
+  SingletonType singletonType() {
+    return singletonType;
+  }
+
+  UnscopedType unscopedTypeBoundAsSingleton() {
+    return unscopedTypeBoundAsSingleton;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/SingletonType.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/SingletonType.java
new file mode 100644
index 0000000..663e858
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/SingletonType.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+final class SingletonType {
+  @Inject SingletonType() {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/StaticChildModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/StaticChildModule.java
new file mode 100644
index 0000000..f7fd490
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/StaticChildModule.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class StaticChildModule {
+  private StaticChildModule() {}
+  
+  @Provides static Object provideStaticObject() {
+    return "static";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/UnscopedType.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/UnscopedType.java
new file mode 100644
index 0000000..89c0085
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/UnscopedType.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import javax.inject.Inject;
+
+final class UnscopedType {
+  @Inject UnscopedType(@SuppressWarnings("unused") SingletonType singletonType) {}
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ChildComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ChildComponent.java
new file mode 100644
index 0000000..b95502c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ChildComponent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding;
+
+import dagger.Subcomponent;
+
+@Subcomponent(modules = test.subcomponent.hiding.b.CommonModuleName.class)
+interface ChildComponent {
+  //ensure that t.s.h.a.CommonName gets bound in this component
+  test.subcomponent.hiding.a.CommonName aCommonName();
+  //ensure that t.s.h.b.CommonName gets bound in this component
+  test.subcomponent.hiding.b.CommonName bCommonName();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ParentComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ParentComponent.java
new file mode 100644
index 0000000..d7c66a6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/ParentComponent.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding;
+
+import dagger.Component;
+import javax.inject.Singleton;
+
+@Component(modules = test.subcomponent.hiding.a.CommonModuleName.class)
+@Singleton
+interface ParentComponent {
+  // ensure that t.s.h.a.CommonName gets bound in this component
+  test.subcomponent.hiding.a.CommonName aCommonName();
+
+  ChildComponent newChildComponent();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonModuleName.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonModuleName.java
new file mode 100644
index 0000000..ad69289
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonModuleName.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding.a;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class CommonModuleName {
+  @Provides String provideString() {
+    return "a";
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonName.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonName.java
new file mode 100644
index 0000000..b2aefda
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/a/CommonName.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding.a;
+
+import javax.inject.Inject;
+
+public final class CommonName {
+  private final String s;
+
+  @Inject CommonName(String s) {
+    this.s = s;
+  }
+
+  @Override
+  public String toString() {
+    return s;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonModuleName.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonModuleName.java
new file mode 100644
index 0000000..66deab5
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonModuleName.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding.b;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class CommonModuleName {
+  @Provides int provideString() {
+    return 1;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonName.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonName.java
new file mode 100644
index 0000000..023cbdb
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/hiding/b/CommonName.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding.b;
+
+import javax.inject.Inject;
+
+public final class CommonName {
+  private final int i;
+
+  @Inject CommonName(int i) {
+    this.i = i;
+  }
+
+  @Override
+  public String toString() {
+    return Integer.toString(i);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInChild.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInChild.java
new file mode 100644
index 0000000..2dd8d20
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInChild.java
@@ -0,0 +1,5 @@
+package test.subcomponent.repeat;
+
+abstract class OnlyUsedInChild {
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInParent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInParent.java
new file mode 100644
index 0000000..cc22b1e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/OnlyUsedInParent.java
@@ -0,0 +1,5 @@
+package test.subcomponent.repeat;
+
+abstract class OnlyUsedInParent {
+
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/ParentComponent.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/ParentComponent.java
new file mode 100644
index 0000000..f0af002
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/ParentComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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 test.subcomponent.repeat;
+
+import dagger.Component;
+import java.util.Set;
+
+@Component(modules = RepeatedModule.class)
+interface ParentComponent {
+  Object state();
+
+  String getString();
+  Set<String> getMultiboundStrings();
+  OnlyUsedInParent getOnlyUsedInParent();
+
+  SubcomponentWithRepeatedModule.Builder newChildComponentBuilder();
+
+  SubcomponentWithoutRepeatedModule newChildComponentWithoutRepeatedModule();
+
+  @Component.Builder
+  interface Builder {
+    Builder repeatedModule(RepeatedModule repeatedModule);
+
+    ParentComponent build();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/RepeatedModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/RepeatedModule.java
new file mode 100644
index 0000000..d099751
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/RepeatedModule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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 test.subcomponent.repeat;
+
+import dagger.Module;
+import dagger.Provides;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+final class RepeatedModule {
+  private final Object state = new Object();
+
+  @Provides
+  Object state() {
+    return state;
+  }
+
+  @Provides
+  static String provideString() {
+    return "a string";
+  }
+
+  @Provides(type = SET)
+  static String contributeString() {
+    return "a string in a set";
+  }
+
+  @Provides
+  static OnlyUsedInParent provideOnlyUsedInParent() {
+    return new OnlyUsedInParent() {};
+  }
+
+  @Provides
+  static OnlyUsedInChild provideOnlyUsedInChild() {
+    return new OnlyUsedInChild() {};
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithRepeatedModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithRepeatedModule.java
new file mode 100644
index 0000000..279bc95
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithRepeatedModule.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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 test.subcomponent.repeat;
+
+import dagger.Subcomponent;
+import java.util.Set;
+
+@Subcomponent(modules = RepeatedModule.class)
+interface SubcomponentWithRepeatedModule {
+  Object state();
+
+  String getString();
+
+  Set<String> getMultiboundStrings();
+
+  OnlyUsedInChild getOnlyUsedInChild();
+
+  @Subcomponent.Builder
+  interface Builder {
+    Builder repeatedModule(RepeatedModule repeatedModule);
+
+    SubcomponentWithRepeatedModule build();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java
new file mode 100644
index 0000000..e63c9a0
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.repeat;
+
+import dagger.Subcomponent;
+
+@Subcomponent
+interface SubcomponentWithoutRepeatedModule {
+  SubcomponentWithRepeatedModule.Builder newGrandchildBuilder();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/CarModule.java b/compiler/src/it/functional-tests/src/main/java/test/tck/CarModule.java
new file mode 100644
index 0000000..bc78517
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/CarModule.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.Module;
+import dagger.Provides;
+import org.atinject.tck.auto.Car;
+import org.atinject.tck.auto.Convertible;
+
+@Module
+class CarModule {
+  @Provides
+  Car provideConvertible(Convertible convertible) {
+    return convertible;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/CarShop.java b/compiler/src/it/functional-tests/src/main/java/test/tck/CarShop.java
new file mode 100644
index 0000000..e42532e
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/CarShop.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.Component;
+import org.atinject.tck.auto.Car;
+import javax.inject.Singleton;
+
+@Singleton
+@Component(
+  modules = {
+    CarModule.class,
+    TireModule.class,
+    SeatModule.class,
+    EngineModule.class,
+    FuelTankModule.class
+  }
+)
+public interface CarShop {
+  @SuppressWarnings("dependency-cycle")
+  Car make();
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/EngineModule.java b/compiler/src/it/functional-tests/src/main/java/test/tck/EngineModule.java
new file mode 100644
index 0000000..577fb5b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/EngineModule.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.MembersInjector;
+import dagger.Module;
+import dagger.Provides;
+import org.atinject.tck.auto.Engine;
+import org.atinject.tck.auto.V8Engine;
+
+@Module
+public class EngineModule {
+  @Provides
+  Engine provideEngine(MembersInjector<V8Engine> injector) {
+    // This is provided because V8Engine has no @Inject constructor and Dagger requires an @Inject
+    // constructor, however this is a TCK supplied class that we prefer to leave unmodified.
+    V8Engine engine = new V8Engine();
+    injector.injectMembers(engine);
+    return engine;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/FuelTankModule.java b/compiler/src/it/functional-tests/src/main/java/test/tck/FuelTankModule.java
new file mode 100644
index 0000000..931556c
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/FuelTankModule.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.Module;
+import dagger.Provides;
+import org.atinject.tck.auto.FuelTank;
+
+@Module
+class FuelTankModule {
+  @Provides
+  FuelTank provideFuelTank() {
+    return new FuelTank();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/SeatModule.java b/compiler/src/it/functional-tests/src/main/java/test/tck/SeatModule.java
new file mode 100644
index 0000000..5c6b729
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/SeatModule.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.Module;
+import dagger.Provides;
+import org.atinject.tck.auto.Drivers;
+import org.atinject.tck.auto.DriversSeat;
+import org.atinject.tck.auto.Seat;
+
+@Module
+class SeatModule {
+  @Provides
+  @Drivers
+  Seat provideSeat(DriversSeat seat) {
+    return seat;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/main/java/test/tck/TireModule.java b/compiler/src/it/functional-tests/src/main/java/test/tck/TireModule.java
new file mode 100644
index 0000000..914a6d6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/main/java/test/tck/TireModule.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import dagger.Module;
+import dagger.Provides;
+import org.atinject.tck.auto.Tire;
+import org.atinject.tck.auto.accessories.SpareTire;
+import javax.inject.Named;
+
+@Module
+class TireModule {
+  @Provides
+  @Named("spare")
+  Tire provideTire(SpareTire sparetire) {
+    return sparetire;
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/BasicTest.java b/compiler/src/it/functional-tests/src/test/java/test/BasicTest.java
new file mode 100644
index 0000000..fe9c6af
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/BasicTest.java
@@ -0,0 +1,116 @@
+/*
+* Copyright (C) 2014 Google, Inc.
+*
+* 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 test;
+
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+import static com.google.common.truth.Truth.assertThat;
+import static test.PrimitivesModule.BOUND_BOOLEAN;
+import static test.PrimitivesModule.BOUND_BOOLEAN_ARRAY;
+import static test.PrimitivesModule.BOUND_BYTE;
+import static test.PrimitivesModule.BOUND_BYTE_ARRAY;
+import static test.PrimitivesModule.BOUND_CHAR;
+import static test.PrimitivesModule.BOUND_CHAR_ARRAY;
+import static test.PrimitivesModule.BOUND_DOUBLE;
+import static test.PrimitivesModule.BOUND_DOUBLE_ARRAY;
+import static test.PrimitivesModule.BOUND_FLOAT;
+import static test.PrimitivesModule.BOUND_FLOAT_ARRAY;
+import static test.PrimitivesModule.BOUND_INT;
+import static test.PrimitivesModule.BOUND_INT_ARRAY;
+import static test.PrimitivesModule.BOUND_LONG;
+import static test.PrimitivesModule.BOUND_LONG_ARRAY;
+import static test.PrimitivesModule.BOUND_SHORT;
+import static test.PrimitivesModule.BOUND_SHORT_ARRAY;
+
+@RunWith(Theories.class)
+public class BasicTest {
+  @DataPoint
+  public static final BasicComponent basicComponent = DaggerBasicComponent.create();
+  @DataPoint
+  public static final BasicComponent abstractClassBasicComponent =
+      DaggerBasicAbstractClassComponent.create();
+
+  @Theory public void primitives(BasicComponent basicComponent) {
+    assertThat(basicComponent.getByte()).isEqualTo(BOUND_BYTE);
+    assertThat(basicComponent.getChar()).isEqualTo(BOUND_CHAR);
+    assertThat(basicComponent.getShort()).isEqualTo(BOUND_SHORT);
+    assertThat(basicComponent.getInt()).isEqualTo(BOUND_INT);
+    assertThat(basicComponent.getLong()).isEqualTo(BOUND_LONG);
+    assertThat(basicComponent.getBoolean()).isEqualTo(BOUND_BOOLEAN);
+    assertThat(basicComponent.getFloat()).isEqualTo(BOUND_FLOAT);
+    assertThat(basicComponent.getDouble()).isEqualTo(BOUND_DOUBLE);
+  }
+
+  @Theory public void boxedPrimitives(BasicComponent basicComponent) {
+    assertThat(basicComponent.getBoxedByte()).isEqualTo(new Byte(BOUND_BYTE));
+    assertThat(basicComponent.getBoxedChar()).isEqualTo(new Character(BOUND_CHAR));
+    assertThat(basicComponent.getBoxedShort()).isEqualTo(new Short(BOUND_SHORT));
+    assertThat(basicComponent.getBoxedInt()).isEqualTo(new Integer(BOUND_INT));
+    assertThat(basicComponent.getBoxedLong()).isEqualTo(new Long(BOUND_LONG));
+    assertThat(basicComponent.getBoxedBoolean()).isEqualTo(new Boolean(BOUND_BOOLEAN));
+    assertThat(basicComponent.getBoxedFloat()).isEqualTo(new Float(BOUND_FLOAT));
+    assertThat(basicComponent.getBoxedDouble()).isEqualTo(new Double(BOUND_DOUBLE));
+  }
+
+  @Theory public void boxedPrimitiveProviders(BasicComponent basicComponent) {
+    assertThat(basicComponent.getByteProvider().get()).isEqualTo(new Byte(BOUND_BYTE));
+    assertThat(basicComponent.getCharProvider().get()).isEqualTo(new Character(BOUND_CHAR));
+    assertThat(basicComponent.getShortProvider().get()).isEqualTo(new Short(BOUND_SHORT));
+    assertThat(basicComponent.getIntProvider().get()).isEqualTo(new Integer(BOUND_INT));
+    assertThat(basicComponent.getLongProvider().get()).isEqualTo(new Long(BOUND_LONG));
+    assertThat(basicComponent.getBooleanProvider().get()).isEqualTo(new Boolean(BOUND_BOOLEAN));
+    assertThat(basicComponent.getFloatProvider().get()).isEqualTo(new Float(BOUND_FLOAT));
+    assertThat(basicComponent.getDoubleProvider().get()).isEqualTo(new Double(BOUND_DOUBLE));
+  }
+
+  @Theory public void primitiveArrays(BasicComponent basicComponent) {
+    assertThat(basicComponent.getByteArray()).isSameAs(BOUND_BYTE_ARRAY);
+    assertThat(basicComponent.getCharArray()).isSameAs(BOUND_CHAR_ARRAY);
+    assertThat(basicComponent.getShortArray()).isSameAs(BOUND_SHORT_ARRAY);
+    assertThat(basicComponent.getIntArray()).isSameAs(BOUND_INT_ARRAY);
+    assertThat(basicComponent.getLongArray()).isSameAs(BOUND_LONG_ARRAY);
+    assertThat(basicComponent.getBooleanArray()).isSameAs(BOUND_BOOLEAN_ARRAY);
+    assertThat(basicComponent.getFloatArray()).isSameAs(BOUND_FLOAT_ARRAY);
+    assertThat(basicComponent.getDoubleArray()).isSameAs(BOUND_DOUBLE_ARRAY);
+  }
+
+  @Theory public void primitiveArrayProviders(BasicComponent basicComponent) {
+    assertThat(basicComponent.getByteArrayProvider().get()).isSameAs(BOUND_BYTE_ARRAY);
+    assertThat(basicComponent.getCharArrayProvider().get()).isSameAs(BOUND_CHAR_ARRAY);
+    assertThat(basicComponent.getShortArrayProvider().get()).isSameAs(BOUND_SHORT_ARRAY);
+    assertThat(basicComponent.getIntArrayProvider().get()).isSameAs(BOUND_INT_ARRAY);
+    assertThat(basicComponent.getLongArrayProvider().get()).isSameAs(BOUND_LONG_ARRAY);
+    assertThat(basicComponent.getBooleanArrayProvider().get()).isSameAs(BOUND_BOOLEAN_ARRAY);
+    assertThat(basicComponent.getFloatArrayProvider().get()).isSameAs(BOUND_FLOAT_ARRAY);
+    assertThat(basicComponent.getDoubleArrayProvider().get()).isSameAs(BOUND_DOUBLE_ARRAY);
+  }
+
+  @Theory public void noOpMembersInjection(BasicComponent basicComponent) {
+    Object object = new Object();
+    assertThat(basicComponent.noOpMembersInjection(object)).isSameAs(object);
+  }
+
+  @Theory public void basicObject_noDeps(BasicComponent basicComponent) {
+    assertThat(basicComponent.thing()).isNotNull();
+  }
+
+  @Theory public void inheritedMembersInjection(BasicComponent basicComponent) {
+    assertThat(basicComponent.typeWithInheritedMembersInjection().thing).isNotNull();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/DependsOnGeneratedCodeTest.java b/compiler/src/it/functional-tests/src/test/java/test/DependsOnGeneratedCodeTest.java
new file mode 100644
index 0000000..0310df6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/DependsOnGeneratedCodeTest.java
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class DependsOnGeneratedCodeTest {
+  @Test public void testComponentDependsOnGeneratedCode() {
+    assertThat(DaggerComponentDependsOnGeneratedCode.create().needsFactory()).isNotNull();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/GenericTest.java b/compiler/src/it/functional-tests/src/test/java/test/GenericTest.java
new file mode 100644
index 0000000..f1c981f
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/GenericTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import test.sub.Exposed;
+import test.sub.PublicSubclass;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(JUnit4.class)
+public class GenericTest {
+
+  @Test public void testGenericComponentCreate() {
+    GenericComponent component = DaggerGenericComponent.create();
+    assertThat(component).isNotNull();
+  }
+  
+  @Test public void testGenericSimpleReferences() {
+    GenericComponent component = DaggerGenericComponent.create();
+    assertThat(component.referencesGeneric().genericA.t).isNotNull();    
+  }
+  
+  @Test public void testGenericDoubleReferences() {
+    GenericComponent component = DaggerGenericComponent.create();
+    GenericDoubleReferences<A> doubleA = component.doubleGenericA();
+    assertThat(doubleA.a).isNotNull();
+    assertThat(doubleA.a2).isNotNull();
+    assertThat(doubleA.t).isNotNull();
+    assertThat(doubleA.t2).isNotNull();
+
+    GenericDoubleReferences<B> doubleB = component.doubleGenericB();
+    assertThat(doubleB.a).isNotNull();
+    assertThat(doubleB.a2).isNotNull();
+    assertThat(doubleB.t).isNotNull();
+    assertThat(doubleB.t2).isNotNull();
+  }
+  
+  @Test public void complexGenerics() {
+    GenericComponent component = DaggerGenericComponent.create();
+    // validate these can be called w/o exceptions.
+    component.complexGenerics();
+  }
+  
+  @Test public void noDepsGenerics() {
+    GenericComponent component = DaggerGenericComponent.create();
+    // validate these can be called w/o exceptions.
+    component.noDepsA();
+    component.noDepsB();
+  }
+  
+  @Test public void boundedGenerics() {
+    BoundedGenericModule expected = new BoundedGenericModule();
+    BoundedGenericComponent component = DaggerBoundedGenericComponent.create();
+    BoundedGenerics<Integer, ArrayList<String>, LinkedList<CharSequence>, Integer, List<Integer>>
+        b1 = component.bounds1();
+    assertEquals(expected.provideInteger(), b1.a);
+    assertEquals(expected.provideArrayListString(), b1.b);
+    assertEquals(expected.provideLinkedListCharSeq(), b1.c);
+    assertEquals(expected.provideInteger(), b1.d);
+    assertEquals(expected.provideListOfInteger(), b1.e);
+
+    BoundedGenerics<Double, LinkedList<String>, LinkedList<Comparable<String>>, Double, Set<Double>>
+        b2 = component.bounds2();
+    assertEquals(expected.provideDouble(), b2.a);
+    assertEquals(expected.provideLinkedListString(), b2.b);
+    assertEquals(expected.provideArrayListOfComparableString(), b2.c);
+    assertEquals(expected.provideDouble(), b2.d);
+    assertEquals(expected.provideSetOfDouble(), b2.e);
+  }
+  
+  @Test public void membersInjections() {
+    GenericComponent component = DaggerGenericComponent.create();
+    GenericChild<A> childA = new GenericChild<A>();
+    component.injectA(childA);
+    assertThat(childA.a).isNotNull();
+    assertThat(childA.b).isNotNull();
+    assertThat(childA.registeredA).isNotNull();
+    assertThat(childA.registeredB).isNotNull();
+    assertThat(childA.registeredT).isNotNull();
+    assertThat(childA.registeredX).isNotNull();
+    assertThat(childA.registeredY).isNotNull();
+    
+    GenericChild<B> childB = new GenericChild<B>();
+    component.injectB(childB);
+    assertThat(childB.a).isNotNull();
+    assertThat(childB.b).isNotNull();
+    assertThat(childB.registeredA).isNotNull();
+    assertThat(childB.registeredB).isNotNull();
+    assertThat(childB.registeredT).isNotNull();
+    assertThat(childB.registeredX).isNotNull();
+    assertThat(childB.registeredY).isNotNull();
+  }
+  
+  @Test public void packagePrivateTypeParameterDependencies() {
+    GenericComponent component = DaggerGenericComponent.create();
+    Exposed exposed = component.exposed();
+    assertThat(exposed.gpp.t).isNotNull();
+    assertThat(exposed.gpp2).isNotNull();
+  }
+  
+  @SuppressWarnings("rawtypes")
+  @Test public void publicSubclassWithPackagePrivateTypeParameterOfSuperclass() {
+    GenericComponent component = DaggerGenericComponent.create();
+    PublicSubclass publicSubclass = component.publicSubclass();
+    assertThat(((Generic)publicSubclass).t).isNotNull();
+  }
+  
+  @Test public void singletonScopesAppliesToEachResolvedType() {
+    SingletonGenericComponent component = DaggerSingletonGenericComponent.create();
+    ScopedGeneric<A> a = component.scopedGenericA();
+    assertThat(a).isSameAs(component.scopedGenericA());
+    assertThat(a.t).isNotNull();
+    
+    ScopedGeneric<B> b = component.scopedGenericB();
+    assertThat(b).isSameAs(component.scopedGenericB());
+    assertThat(b.t).isNotNull();
+    
+    assertThat(a).isNotSameAs(b);
+  }
+  
+  @Test public void genericModules() {
+    GenericComponent component = DaggerGenericComponent.create();
+    assertThat(component.iterableInt()).containsExactly(1, 2).inOrder();
+    assertThat(component.iterableDouble()).containsExactly(3d, 4d).inOrder();
+    
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/MultibindingTest.java b/compiler/src/it/functional-tests/src/test/java/test/MultibindingTest.java
new file mode 100644
index 0000000..1b7e302
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/MultibindingTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import com.google.auto.value.AutoAnnotation;
+import com.google.common.collect.ImmutableMap;
+import dagger.mapkeys.ClassKey;
+import dagger.mapkeys.StringKey;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Map;
+import javax.inject.Provider;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class MultibindingTest {
+  private MultibindingComponent multibindingComponent;
+
+  @Before public void setUp() {
+    multibindingComponent = DaggerMultibindingComponent.builder()
+        .multibindingDependency(new MultibindingDependency() {
+          @Override public double doubleDependency() {
+            return 0.0;
+          }
+        })
+        .build();
+  }
+
+  @Test public void map() {
+    Map<String, String> map = multibindingComponent.map();
+    assertThat(map).hasSize(2);
+    assertThat(map).containsEntry("foo", "foo value");
+    assertThat(map).containsEntry("bar", "bar value");
+  }
+
+  @Test public void mapOfArrays() {
+    Map<String, String[]> map = multibindingComponent.mapOfArrays();
+    assertThat(map).hasSize(2);
+    assertThat(map).containsKey("foo");
+    assertThat(map.get("foo")).asList().containsExactly("foo1", "foo2").inOrder();
+    assertThat(map).containsKey("bar");
+    assertThat(map.get("bar")).asList().containsExactly("bar1", "bar2").inOrder();
+  }
+
+  @Test public void mapOfProviders() {
+    Map<String, Provider<String>> mapOfProviders = multibindingComponent.mapOfProviders();
+    assertThat(mapOfProviders).hasSize(2);
+    assertThat(mapOfProviders.get("foo").get()).isEqualTo("foo value");
+    assertThat(mapOfProviders.get("bar").get()).isEqualTo("bar value");
+  }
+
+  @Test public void mapKeysAndValues() {
+    assertThat(multibindingComponent.mapKeys()).containsExactly("foo", "bar");
+    assertThat(multibindingComponent.mapValues()).containsExactly("foo value", "bar value");
+  }
+
+  @Test public void nestedKeyMap() {
+    assertThat(multibindingComponent.nestedKeyMap()).isEqualTo(
+        ImmutableMap.of(
+            nestedWrappedKey(Integer.class), "integer",
+            nestedWrappedKey(Long.class), "long"));
+  }
+
+  @Test
+  public void unwrappedAnnotationKeyMap() {
+    assertThat(multibindingComponent.unwrappedAnnotationKeyMap())
+        .isEqualTo(ImmutableMap.of(testStringKey("foo\n"), "foo annotation"));
+  }
+
+  @Test
+  public void wrappedAnnotationKeyMap() {
+    @SuppressWarnings("unchecked")
+    Class<? extends Number>[] classes = new Class[] {Long.class, Integer.class};
+    assertThat(multibindingComponent.wrappedAnnotationKeyMap())
+        .isEqualTo(
+            ImmutableMap.of(
+                testWrappedAnnotationKey(
+                    testStringKey("foo"), new int[] {1, 2, 3}, new ClassKey[] {}, classes),
+                "wrapped foo annotation"));
+  }
+
+  @Test
+  public void booleanKeyMap() {
+    assertThat(multibindingComponent.booleanKeyMap()).isEqualTo(ImmutableMap.of(true, "true"));
+  }
+
+  @Test
+  public void byteKeyMap() {
+    assertThat(multibindingComponent.byteKeyMap())
+        .isEqualTo(ImmutableMap.of((byte) 100, "100 byte"));
+  }
+
+  @Test
+  public void charKeyMap() {
+    assertThat(multibindingComponent.characterKeyMap())
+        .isEqualTo(ImmutableMap.of('a', "a char", '\n', "newline char"));
+  }
+
+  @Test
+  public void classKeyMap() {
+    assertThat(multibindingComponent.classKeyMap())
+        .isEqualTo(
+            ImmutableMap.of(
+                Integer.class, "integer",
+                Long.class, "long"));
+  }
+
+  @Test
+  public void numberClassKeyMap() {
+    assertThat(multibindingComponent.numberClassKeyMap())
+        .isEqualTo(
+            ImmutableMap.of(
+                BigDecimal.class, "bigdecimal",
+                BigInteger.class, "biginteger"));
+  }
+
+  @Test
+  public void intKeyMap() {
+    assertThat(multibindingComponent.integerKeyMap()).isEqualTo(ImmutableMap.of(100, "100 int"));
+  }
+
+  @Test
+  public void longKeyMap() {
+    assertThat(multibindingComponent.longKeyMap())
+        .isEqualTo(ImmutableMap.of((long) 100, "100 long"));
+  }
+
+  @Test
+  public void shortKeyMap() {
+    assertThat(multibindingComponent.shortKeyMap())
+        .isEqualTo(ImmutableMap.of((short) 100, "100 short"));
+  }
+
+  @Test public void setBindings() {
+    assertThat(multibindingComponent.set()).containsExactly(-90, -17, -1, 5, 6, 832, 1742);
+  }
+
+  @Test public void complexQualifierSet() {
+    assertThat(multibindingComponent.complexQualifierStringSet()).containsExactly("foo");
+  }
+
+  @AutoAnnotation
+  static StringKey testStringKey(String value) {
+    return new AutoAnnotation_MultibindingTest_testStringKey(value);
+  }
+
+  @AutoAnnotation
+  static NestedAnnotationContainer.NestedWrappedKey nestedWrappedKey(Class<?> value) {
+    return new AutoAnnotation_MultibindingTest_nestedWrappedKey(value);
+  }
+
+  @AutoAnnotation
+  static WrappedAnnotationKey testWrappedAnnotationKey(
+      StringKey value, int[] integers, ClassKey[] annotations, Class<? extends Number>[] classes) {
+    return new AutoAnnotation_MultibindingTest_testWrappedAnnotationKey(
+        value, integers, annotations, classes);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/NestedTest.java b/compiler/src/it/functional-tests/src/test/java/test/NestedTest.java
new file mode 100644
index 0000000..14c3e53
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/NestedTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class NestedTest {
+  @Test public void nestedFoo() {
+    OuterClassFoo.NestedComponent nestedFoo = DaggerOuterClassFoo_NestedComponent.create();
+    assertThat(nestedFoo.thing()).isNotNull();
+  }
+
+  @Test public void nestedBar() {
+    OuterClassBar.NestedComponent nestedBar = DaggerOuterClassBar_NestedComponent.create();
+    assertThat(nestedBar.injectedThing()).isNotNull();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/NonComponentDependencyTest.java b/compiler/src/it/functional-tests/src/test/java/test/NonComponentDependencyTest.java
new file mode 100644
index 0000000..37d3f7a
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/NonComponentDependencyTest.java
@@ -0,0 +1,34 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class NonComponentDependencyTest {
+  @Test public void testThing() {
+    NonComponentDependencyComponent component =
+        DaggerNonComponentDependencyComponent.builder()
+            .thingComponent(new NonComponentDependencyComponent.ThingComponentImpl())
+            .build();
+    assertThat(component).isNotNull();
+    assertThat(component.thingTwo()).isNotNull();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/builder/BuilderTest.java b/compiler/src/it/functional-tests/src/test/java/test/builder/BuilderTest.java
new file mode 100644
index 0000000..46f5388
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/builder/BuilderTest.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.builder;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public class BuilderTest {
+
+  @Test public void interfaceBuilder() {
+    TestComponentWithBuilderInterface.Builder builder =
+        DaggerTestComponentWithBuilderInterface.builder();
+
+    // Make sure things fail if we don't set our required modules.
+    try {
+      builder.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder.intModule(new IntModuleIncludingDoubleAndFloat(1))
+        .stringModule(new StringModule("sam"))
+        .depComponent(new DepComponent() {});
+    builder.doubleModule(new DoubleModule());
+    // Don't set other modules -- make sure it works.
+    
+    TestComponentWithBuilderInterface component = builder.build();
+    assertThat(component.s()).isEqualTo("sam");
+    assertThat(component.i()).isEqualTo(1);
+    assertThat(component.d()).isWithin(0).of(4.2d);
+    assertThat(component.f()).isEqualTo(5.5f);
+    assertThat(component.l()).isEqualTo(6L);
+  }
+
+  @Test public void abstractClassBuilder() {
+    TestComponentWithBuilderAbstractClass.Builder builder =
+        TestComponentWithBuilderAbstractClass.builder();
+
+    // Make sure things fail if we don't set our required modules.
+    try {
+      builder.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder.intModule(new IntModuleIncludingDoubleAndFloat(1))
+        .stringModule(new StringModule("sam"))
+        .depComponent(new DepComponent() {});
+    builder.doubleModule(new DoubleModule());
+    // Don't set other modules -- make sure it works.
+    
+    TestComponentWithBuilderAbstractClass component = builder.build();
+    assertThat(component.s()).isEqualTo("sam");
+    assertThat(component.i()).isEqualTo(1);
+    assertThat(component.d()).isWithin(0).of(4.2d);
+    assertThat(component.f()).isEqualTo(5.5f);
+    assertThat(component.l()).isEqualTo(6L);
+  }
+
+  @Test public void interfaceGenericBuilder() {
+    TestComponentWithGenericBuilderInterface.Builder builder =
+        DaggerTestComponentWithGenericBuilderInterface.builder();
+
+    // Make sure things fail if we don't set our required modules.
+    try {
+      builder.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder.setM2(new IntModuleIncludingDoubleAndFloat(1))
+        .setM1(new StringModule("sam"))
+        .depComponent(new DepComponent() {});
+    builder.doubleModule(new DoubleModule());
+    // Don't set other modules -- make sure it works.
+    
+    TestComponentWithGenericBuilderInterface component = builder.build();
+    assertThat(component.s()).isEqualTo("sam");
+    assertThat(component.i()).isEqualTo(1);
+    assertThat(component.d()).isWithin(0).of(4.2d);
+    assertThat(component.f()).isEqualTo(5.5f);
+    assertThat(component.l()).isEqualTo(6L);
+  }
+
+  @Test public void abstractClassGenericBuilder() {
+    TestComponentWithGenericBuilderAbstractClass.Builder builder =
+        DaggerTestComponentWithGenericBuilderAbstractClass.builder();
+
+    // Make sure things fail if we don't set our required modules.
+    try {
+      builder.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder.setM2(new IntModuleIncludingDoubleAndFloat(1))
+        .setM1(new StringModule("sam"))
+        .depComponent(new DepComponent() {});
+    builder.doubleModule(new DoubleModule());
+    // Don't set other modules -- make sure it works.
+    
+    TestComponentWithGenericBuilderAbstractClass component = builder.build();
+    assertThat(component.s()).isEqualTo("sam");
+    assertThat(component.i()).isEqualTo(1);
+    assertThat(component.d()).isWithin(0).of(4.2d);
+    assertThat(component.f()).isEqualTo(5.5f);
+    assertThat(component.l()).isEqualTo(6L);
+  }
+  
+  @Test public void subcomponents_interface() {
+    ParentComponent parent = DaggerParentComponent.create();    
+    TestChildComponentWithBuilderInterface.Builder builder1 = parent.childInterfaceBuilder();
+    try {
+      builder1.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder1.setM2(new IntModuleIncludingDoubleAndFloat(1))
+        .setM1(new StringModule("sam"))
+        .set(new ByteModule((byte)7));
+    builder1.set(new FloatModule());
+    TestChildComponentWithBuilderInterface child1 = builder1.build();
+    assertThat(child1.s()).isEqualTo("sam");
+    assertThat(child1.i()).isEqualTo(1);
+    assertThat(child1.d()).isWithin(0).of(4.2d);
+    assertThat(child1.f()).isEqualTo(5.5f);
+    assertThat(child1.l()).isEqualTo(6L);
+    assertThat(child1.b()).isEqualTo((byte)7);
+  }
+  
+  @Test public void subcomponents_abstractclass() {
+    ParentComponent parent = DaggerParentComponent.create();
+    TestChildComponentWithBuilderAbstractClass.Builder builder2 =
+        parent.childAbstractClassBuilder();
+    try {
+      builder2.build();
+      fail();
+    } catch(IllegalStateException expected) {}
+    
+    builder2.setM2(new IntModuleIncludingDoubleAndFloat(10))
+        .setM1(new StringModule("tara"))
+        .set(new ByteModule((byte)70));
+    builder2.set(new FloatModule());
+    TestChildComponentWithBuilderAbstractClass child2 = builder2.build();
+    assertThat(child2.s()).isEqualTo("tara");
+    assertThat(child2.i()).isEqualTo(10);
+    assertThat(child2.d()).isWithin(0).of(4.2d);
+    assertThat(child2.f()).isEqualTo(5.5f);
+    assertThat(child2.l()).isEqualTo(6L);
+    assertThat(child2.b()).isEqualTo((byte)70);
+  }
+    
+  @Test
+  public void grandchildren() {
+    ParentComponent parent = DaggerParentComponent.create();
+    MiddleChild middle1 = parent.middleBuilder().set(new StringModule("sam")).build();
+    Grandchild grandchild1 =
+        middle1.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(21)).build();
+    Grandchild grandchild2 =
+        middle1.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(22)).build();
+    
+    assertThat(middle1.s()).isEqualTo("sam");
+    assertThat(grandchild1.i()).isEqualTo(21);
+    assertThat(grandchild1.s()).isEqualTo("sam");
+    assertThat(grandchild2.i()).isEqualTo(22);
+    assertThat(grandchild2.s()).isEqualTo("sam");
+
+    // Make sure grandchildren from newer children have no relation to the older ones.
+    MiddleChild middle2 = parent.middleBuilder().set(new StringModule("tara")).build();
+    Grandchild grandchild3 =
+        middle2.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(23)).build();
+    Grandchild grandchild4 =
+        middle2.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(24)).build();
+    
+    assertThat(middle2.s()).isEqualTo("tara");
+    assertThat(grandchild3.i()).isEqualTo(23);
+    assertThat(grandchild3.s()).isEqualTo("tara");
+    assertThat(grandchild4.i()).isEqualTo(24);
+    assertThat(grandchild4.s()).isEqualTo("tara");
+  }
+  
+  @Test
+  public void diamondGrandchildren() {
+    ParentComponent parent = DaggerParentComponent.create();
+    MiddleChild middle = parent.middleBuilder().set(new StringModule("sam")).build();
+    OtherMiddleChild other = parent.otherBuilder().set(new StringModule("tara")).build();
+    
+    Grandchild middlegrand =
+        middle.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(21)).build();
+    Grandchild othergrand =
+        other.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(22)).build();
+    
+    assertThat(middle.s()).isEqualTo("sam");
+    assertThat(other.s()).isEqualTo("tara");
+    assertThat(middlegrand.s()).isEqualTo("sam");
+    assertThat(othergrand.s()).isEqualTo("tara");
+    assertThat(middlegrand.i()).isEqualTo(21);
+    assertThat(othergrand.i()).isEqualTo(22);
+  }
+  
+  @Test
+  public void genericSubcomponentMethod() {
+    ParentOfGenericComponent parent =
+        DaggerParentOfGenericComponent.builder().stringModule(new StringModule("sam")).build();
+    Grandchild.Builder builder = parent.subcomponentBuilder();
+    Grandchild child = builder.set(new IntModuleIncludingDoubleAndFloat(21)).build();
+    assertThat(child.s()).isEqualTo("sam");
+    assertThat(child.i()).isEqualTo(21);
+  }
+  
+  @Test
+  public void requireSubcomponentBuilderProviders() {
+    ParentComponent parent = DaggerParentComponent.create();
+    MiddleChild middle =
+        parent
+            .requiresMiddleChildBuilder()
+            .subcomponentBuilderProvider()
+            .get()
+            .set(new StringModule("sam"))
+            .build();
+    Grandchild grandchild =
+        middle
+            .requiresGrandchildBuilder()
+            .subcomponentBuilderProvider()
+            .get()
+            .set(new IntModuleIncludingDoubleAndFloat(12))
+            .build();
+    assertThat(middle.s()).isEqualTo("sam");
+    assertThat(grandchild.i()).isEqualTo(12);
+    assertThat(grandchild.s()).isEqualTo("sam");
+  }
+  
+  @Test
+  public void requireSubcomponentBuilders() {
+    ParentComponent parent = DaggerParentComponent.create();
+    MiddleChild middle =
+        parent
+            .requiresMiddleChildBuilder()
+            .subcomponentBuilder()
+            .set(new StringModule("sam"))
+            .build();
+    Grandchild grandchild =
+        middle
+            .requiresGrandchildBuilder()
+            .subcomponentBuilder()
+            .set(new IntModuleIncludingDoubleAndFloat(12))
+            .build();
+    assertThat(middle.s()).isEqualTo("sam");
+    assertThat(grandchild.i()).isEqualTo(12);
+    assertThat(grandchild.s()).isEqualTo("sam");
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/cycle/CycleTest.java b/compiler/src/it/functional-tests/src/test/java/test/cycle/CycleTest.java
new file mode 100644
index 0000000..d3bc2cb
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/cycle/CycleTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.cycle;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import test.cycle.Cycles.A;
+import test.cycle.Cycles.C;
+import test.cycle.Cycles.ChildCycleComponent;
+import test.cycle.Cycles.CycleComponent;
+import test.cycle.Cycles.CycleMapComponent;
+import test.cycle.Cycles.S;
+import test.cycle.Cycles.SelfCycleComponent;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class CycleTest {
+  @Test
+  public void providerIndirectionSelfCycle() {
+    SelfCycleComponent selfCycleComponent = DaggerCycles_SelfCycleComponent.create();
+    S s = selfCycleComponent.s();
+    assertThat(s.sProvider.get()).isNotNull();
+  }
+
+  @Test
+  public void providerIndirectionCycle() {
+    CycleComponent cycleComponent = DaggerCycles_CycleComponent.create();
+    A a = cycleComponent.a();
+    C c = cycleComponent.c();
+    assertThat(c.aProvider.get()).isNotNull();
+    assertThat(a.b.c.aProvider.get()).isNotNull();
+    assertThat(a.e.d.b.c.aProvider.get()).isNotNull();
+  }
+
+  @Test
+  public void lazyIndirectionSelfCycle() {
+    SelfCycleComponent selfCycleComponent = DaggerCycles_SelfCycleComponent.create();
+    S s = selfCycleComponent.s();
+    assertThat(s.sLazy.get()).isNotNull();
+  }
+
+  @Test
+  public void lazyIndirectionCycle() {
+    CycleComponent cycleComponent = DaggerCycles_CycleComponent.create();
+    A a = cycleComponent.a();
+    C c = cycleComponent.c();
+    assertThat(c.aLazy.get()).isNotNull();
+    assertThat(a.b.c.aLazy.get()).isNotNull();
+    assertThat(a.e.d.b.c.aLazy.get()).isNotNull();
+  }
+  
+  @Test
+  public void subcomponentIndirectionCycle() {
+    ChildCycleComponent childCycleComponent = DaggerCycles_CycleComponent.create().child();
+    A a = childCycleComponent.a();
+    assertThat(a.b.c.aProvider.get()).isNotNull();
+    assertThat(a.e.d.b.c.aProvider.get()).isNotNull();
+  }
+  
+  @Test
+  public void providerMapIndirectionCycle() {
+    CycleMapComponent cycleMapComponent = DaggerCycles_CycleMapComponent.create();
+    assertThat(cycleMapComponent.y()).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfX).containsKey("X");
+    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X")).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X").get()).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X").get().y).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfX).hasSize(1);
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY).containsKey("Y");
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y")).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get()).isNotNull();
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get().mapOfProvidersOfX).hasSize(1);
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get().mapOfProvidersOfY).hasSize(1);
+    assertThat(cycleMapComponent.y().mapOfProvidersOfY).hasSize(1);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/cycle/LongCycleTest.java b/compiler/src/it/functional-tests/src/test/java/test/cycle/LongCycleTest.java
new file mode 100644
index 0000000..e50eaee
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/cycle/LongCycleTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.cycle;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import test.cycle.LongCycle.LongCycleComponent;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class LongCycleTest {
+  
+  /**
+   * Tests a cycle long enough that the real factory is created in a separate initialize method from
+   * the delegate factory.
+   */
+  @Test
+  public void longCycle() {
+    LongCycleComponent longCycleComponent = DaggerLongCycle_LongCycleComponent.create();
+    assertThat(longCycleComponent.class1()).isNotNull();
+  }
+
+  /**
+   * Fails if {@link LongCycleComponent} doesn't have a long enough cycle to make sure the real
+   * factory is created in a separate method from the delegate factory.
+   */
+  @Test
+  public void longCycleHasMoreThanOneInitializeMethod() throws NoSuchMethodException {
+    DaggerLongCycle_LongCycleComponent.class
+        .getDeclaredMethod("initialize1", DaggerLongCycle_LongCycleComponent.Builder.class);
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/membersinject/MembersInjectTest.java b/compiler/src/it/functional-tests/src/test/java/test/membersinject/MembersInjectTest.java
new file mode 100644
index 0000000..411ecb1
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/membersinject/MembersInjectTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.membersinject;
+
+import dagger.MembersInjector;
+import javax.inject.Provider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import test.multipackage.DaggerMembersInjectionVisibilityComponent;
+import test.multipackage.MembersInjectionVisibilityComponent;
+import test.multipackage.a.AGrandchild;
+import test.multipackage.a.AParent;
+import test.multipackage.b.BChild;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class MembersInjectTest {
+  @Test public void testMembersInject_arrays() {
+    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
+
+    ChildOfStringArray childOfStringArray = new ChildOfStringArray();
+    component.inject(childOfStringArray);
+  }
+
+  @Test public void testMembersInject_nestedArrays() {
+    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
+
+    ChildOfArrayOfParentOfStringArray childOfArrayOfParentOfStringArray =
+        new ChildOfArrayOfParentOfStringArray();
+    component.inject(childOfArrayOfParentOfStringArray);
+  }
+
+  @Test public void testMembersInject_primitives() {
+    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
+
+    ChildOfPrimitiveIntArray childOfPrimitiveIntArray = new ChildOfPrimitiveIntArray();
+    component.inject(childOfPrimitiveIntArray);
+  }
+
+  @Test
+  public void testMembersInject_overrides() {
+    MembersInjectionVisibilityComponent component =
+        DaggerMembersInjectionVisibilityComponent.create();
+    AParent aParent = new AParent();
+    component.inject(aParent);
+    assertThat(aParent.aParentField()).isNotNull();
+    assertThat(aParent.aParentMethod()).isNotNull();
+
+    BChild aChild = new BChild();
+    component.inject(aChild);
+    assertThat(aChild.aParentField()).isNotNull();
+    assertThat(aChild.aParentMethod()).isNull();
+    assertThat(aChild.aChildField()).isNotNull();
+    assertThat(aChild.aChildMethod()).isNotNull();
+
+    AGrandchild aGrandchild = new AGrandchild();
+    component.inject(aGrandchild);
+    assertThat(aGrandchild.aParentField()).isNotNull();
+    assertThat(aGrandchild.aParentMethod()).isNotNull();
+    assertThat(aGrandchild.aChildField()).isNotNull();
+    assertThat(aGrandchild.aChildMethod()).isNull();
+    assertThat(aGrandchild.aGrandchildField()).isNotNull();
+    assertThat(aGrandchild.aGrandchildMethod()).isNotNull();
+  }
+
+  @Test
+  public void testNonRequestedMembersInjector() {
+    NonRequestedChild child = new NonRequestedChild();
+    Provider<String> provider =
+        new Provider<String>() {
+          @Override
+          public String get() {
+            return "field!";
+          }
+        };
+    MembersInjector<NonRequestedChild> injector = new NonRequestedChild_MembersInjector(provider);
+    injector.injectMembers(child);
+    assertThat(child.t).isEqualTo("field!");
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/nullables/NullabilityTest.java b/compiler/src/it/functional-tests/src/test/java/test/nullables/NullabilityTest.java
new file mode 100644
index 0000000..a0e1e22
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/nullables/NullabilityTest.java
@@ -0,0 +1,110 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 test.nullables;
+
+import javax.inject.Provider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public class NullabilityTest {
+  @Test public void testNullability_provides() {
+    NullModule module = new NullModule();
+    NullComponent component = DaggerNullComponent.builder().nullModule(module).build();
+
+    // Can't construct NullFoo because it depends on Number, and Number was null.
+    try {
+      component.nullFoo();
+      fail();
+    } catch (NullPointerException npe) {
+      assertThat(npe).hasMessage("Cannot return null from a non-@Nullable @Provides method");
+    }
+
+    // set number to non-null so we can create
+    module.numberValue = 1;
+    NullFoo nullFoo = component.nullFoo();
+
+    // Then set it back to null so we can test its providers.
+    module.numberValue = null;
+    validate(true, nullFoo.string, nullFoo.stringProvider, nullFoo.numberProvider);
+    validate(true, nullFoo.methodInjectedString, nullFoo.methodInjectedStringProvider,
+        nullFoo.methodInjectedNumberProvider);
+    validate(true, nullFoo.fieldInjectedString, nullFoo.fieldInjectedStringProvider,
+        nullFoo.fieldInjectedNumberProvider);
+  }
+  
+  @Test public void testNullability_components() {
+    NullComponent nullComponent = new NullComponent() {      
+      @Override public Provider<String> stringProvider() {
+        return new Provider<String>() {
+          @Override public String get() {
+            return null;
+          }
+        };
+      }
+      
+      @Override public String string() {
+        return null;
+      }
+      
+      @Override public Provider<Number> numberProvider() {
+        return new Provider<Number>() {
+          @Override public Number get() {
+            return null;
+          }
+        };
+      }
+      
+      @Override public Number number() {
+        return null;
+      }
+      
+      @Override public NullFoo nullFoo() {
+        return null;
+      }
+    };
+    NullComponentWithDependency component =
+        DaggerNullComponentWithDependency.builder().nullComponent(nullComponent).build();
+    validate(false, component.string(), component.stringProvider(), component.numberProvider());
+    
+    // Also validate that the component's number() method fails
+    try {
+      component.number();
+      fail();
+    } catch (NullPointerException npe) {
+      assertThat(npe).hasMessage("Cannot return null from a non-@Nullable component method");
+    }
+  }
+
+  private void validate(boolean fromProvides,
+      String string,
+      Provider<String> stringProvider,
+      Provider<Number> numberProvider) {
+    assertThat(string).isNull();
+    assertThat(numberProvider).isNotNull();
+    try {
+      numberProvider.get();
+      fail();
+    } catch(NullPointerException npe) {
+      assertThat(npe).hasMessage("Cannot return null from a non-@Nullable "
+          + (fromProvides ? "@Provides" : "component") + " method");
+    }
+    assertThat(stringProvider.get()).isNull();
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/staticprovides/StaticProvidesTest.java b/compiler/src/it/functional-tests/src/test/java/test/staticprovides/StaticProvidesTest.java
new file mode 100644
index 0000000..3972594
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/staticprovides/StaticProvidesTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.staticprovides;
+
+import com.google.common.collect.ImmutableSet;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+@RunWith(Parameterized.class)
+public class StaticProvidesTest {
+  @Parameters
+  public static Collection<Object[]> components() {
+    return Arrays.asList(new Object[][] {
+        {DaggerStaticTestComponent.create()},
+        {DaggerStaticTestComponentWithBuilder.builder().build()},
+        {DaggerStaticTestComponentWithBuilder.builder()
+          .allStaticModule(new AllStaticModule())
+          .someStaticModule(new SomeStaticModule())
+          .build()}});
+  }
+
+  @Parameter
+  public StaticTestComponent component;
+
+  @Test public void setMultibinding() {
+    assertThat(component.getMultiboundStrings()).isEqualTo(ImmutableSet.of(
+        AllStaticModule.class + ".contributeString",
+        SomeStaticModule.class + ".contributeStringFromAStaticMethod",
+        SomeStaticModule.class + ".contributeStringFromAnInstanceMethod"));
+  }
+
+  @Test public void allStaticProvidesModules_noFieldInComponentBuilder() {
+    for (Field field : DaggerStaticTestComponent.Builder.class.getDeclaredFields()) {
+      assertWithMessage(field.getName())
+          .that(field.getType()).isNotEqualTo(AllStaticModule.class);
+    }
+  }
+
+  @Test public void allStaticProvidesModules_deprecatedMethodInComponentBuilder() {
+    for (Method method : DaggerStaticTestComponent.Builder.class.getDeclaredMethods()) {
+      if (Arrays.asList(method.getParameterTypes()).contains(AllStaticModule.class)) {
+        assertWithMessage(method.getName())
+            .that(method.isAnnotationPresent(Deprecated.class))
+            .isTrue();
+      }
+    }
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentMultibindingsTest.java b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentMultibindingsTest.java
new file mode 100644
index 0000000..f57a778
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentMultibindingsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+@RunWith(Parameterized.class)
+public class SubcomponentMultibindingsTest {
+
+  @Parameters(name = "{0}")
+  public static Collection<Object[]> parameters() {
+    return ImmutableList.of(
+        new Object[] {DaggerParentComponentWithMultibindings.create()},
+        new Object[] {DaggerParentComponentWithoutMultibindings.create()});
+  }
+
+  private ParentComponentWithoutMultibindings parent;
+
+  public SubcomponentMultibindingsTest(ParentComponentWithoutMultibindings parentComponent) {
+    this.parent = parentComponent;
+  }
+
+  @Test
+  public void testMultibindingsInSubcomponents() {
+    RequiresMultibindingsInChild requiresMultibindingsInChild =
+        parent.childComponent().requiresMultibindingsInChild();
+
+    assertWithMessage("requiresMultiboundObjects.setOfObjects")
+        .that(requiresMultibindingsInChild.requiresMultiboundObjects().setOfObjects())
+        .containsExactly("object provided by parent", "object provided by child");
+
+    assertWithMessage("requiresMultiboundObjects.mapOfObjects")
+        .that(requiresMultibindingsInChild.requiresMultiboundObjects().mapOfObjects())
+        .isEqualTo(
+            ImmutableMap.of("parent key", "object in parent", "child key", "object in child"));
+
+    assertWithMessage("requiresMultiboundStrings")
+        .that(requiresMultibindingsInChild.requiresMultiboundStrings().setOfStrings())
+        .containsExactly("string provided by parent");
+
+    assertWithMessage("requiresMultiboundStrings.mapOfStrings")
+        .that(requiresMultibindingsInChild.requiresMultiboundStrings().mapOfStrings())
+        .isEqualTo(ImmutableMap.of("parent key", "string in parent"));
+  }
+
+  @Test
+  public void testOverriddenMultibindingsInSubcomponents() {
+    RequiresMultibindingsInChild requiresMultibindingsInChild =
+        parent.childComponent().requiresMultibindingsInChild();
+
+    assertWithMessage("setOfRequiresMultiboundObjects")
+        .that(requiresMultibindingsInChild.setOfRequiresMultiboundObjects())
+        .hasSize(1);
+
+    RequiresMultiboundObjects onlyElementInMultiboundRequiresMultiboundObjects =
+        getOnlyElement(requiresMultibindingsInChild.setOfRequiresMultiboundObjects());
+
+    assertWithMessage("setOfRequiresMultiboundObjects[only].setOfObjects")
+        .that(onlyElementInMultiboundRequiresMultiboundObjects.setOfObjects())
+        .containsExactly("object provided by parent", "object provided by child");
+
+    assertWithMessage("setOfRequiresMultiboundObjects[only].mapOfObjects")
+        .that(onlyElementInMultiboundRequiresMultiboundObjects.mapOfObjects())
+        .isEqualTo(
+            ImmutableMap.of("parent key", "object in parent", "child key", "object in child"));
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentTest.java b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentTest.java
new file mode 100644
index 0000000..cb62925
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/SubcomponentTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import static com.google.common.collect.Sets.intersection;
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(Parameterized.class)
+public class SubcomponentTest {
+  private static final ParentComponent parentComponent = DaggerParentComponent.create();
+  private static final ParentOfGenericComponent parentOfGenericComponent =
+      DaggerParentOfGenericComponent.create();
+  
+  @Parameters
+  public static Collection<Object[]> parameters() {
+    return Arrays.asList(new Object[][] {
+        { parentComponent, parentComponent.newChildComponent() },
+        { parentComponent, parentComponent.newChildAbstractClassComponent() },
+        { parentOfGenericComponent, parentOfGenericComponent.subcomponent() }});
+  }        
+  
+  private final ParentGetters parentGetters;
+  private final ChildComponent childComponent;
+  
+  public SubcomponentTest(ParentGetters parentGetters, ChildComponent childComponent) {
+    this.parentGetters = parentGetters;
+    this.childComponent = childComponent;
+  }
+  
+
+  @Test
+  public void scopePropagatesUpward_class() {
+    assertThat(childComponent.requiresSingleton().singletonType())
+        .isSameAs(childComponent.requiresSingleton().singletonType());
+    assertThat(childComponent.requiresSingleton().singletonType())
+        .isSameAs(childComponent.newGrandchildComponent().requiresSingleton().singletonType());
+  }
+
+  @Test
+  public void scopePropagatesUpward_provides() {
+    assertThat(childComponent
+        .requiresSingleton().unscopedTypeBoundAsSingleton())
+            .isSameAs(childComponent
+                .requiresSingleton().unscopedTypeBoundAsSingleton());
+    assertThat(childComponent
+        .requiresSingleton().unscopedTypeBoundAsSingleton())
+            .isSameAs(childComponent.newGrandchildComponent()
+                .requiresSingleton().unscopedTypeBoundAsSingleton());
+  }
+
+  @Test
+  public void multibindingContributions() {
+    Set<Object> parentObjectSet = parentGetters.objectSet();
+    assertThat(parentObjectSet).hasSize(2);
+    Set<Object> childObjectSet = childComponent.objectSet();
+    assertThat(childObjectSet).hasSize(3);
+    Set<Object> grandchildObjectSet =
+        childComponent.newGrandchildComponent().objectSet();
+    assertThat(grandchildObjectSet).hasSize(4);
+    assertThat(intersection(parentObjectSet, childObjectSet)).hasSize(1);
+    assertThat(intersection(parentObjectSet, grandchildObjectSet)).hasSize(1);
+    assertThat(intersection(childObjectSet, grandchildObjectSet)).hasSize(1);
+  }
+
+  @Test
+  public void unscopedProviders() {
+    assertThat(parentGetters.getUnscopedTypeProvider())
+        .isSameAs(childComponent.getUnscopedTypeProvider());
+    assertThat(parentGetters.getUnscopedTypeProvider())
+        .isSameAs(childComponent
+            .newGrandchildComponent()
+            .getUnscopedTypeProvider());
+  }
+
+  @Test
+  public void passedModules() {
+    ChildModuleWithState childModuleWithState = new ChildModuleWithState();
+    ChildComponentRequiringModules childComponent1 =
+        parentComponent.newChildComponentRequiringModules(
+            new ChildModuleWithParameters(new Object()),
+            childModuleWithState);
+    ChildComponentRequiringModules childComponent2 =
+        parentComponent.newChildComponentRequiringModules(
+            new ChildModuleWithParameters(new Object()),
+            childModuleWithState);
+    assertThat(childComponent1.getInt()).isEqualTo(0);
+    assertThat(childComponent2.getInt()).isEqualTo(1);
+  }
+
+  @Test
+  public void dependenceisInASubcomponent() {
+    assertThat(childComponent.newGrandchildComponent().needsAnInterface()).isNotNull();
+  }  
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/subcomponent/hiding/SubcomponentHidingTest.java b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/hiding/SubcomponentHidingTest.java
new file mode 100644
index 0000000..27dcbb6
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/hiding/SubcomponentHidingTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.subcomponent.hiding;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class SubcomponentHidingTest {
+  @Test public void moduleNameHiding() {
+    ParentComponent parent = DaggerParentComponent.create();
+    assertThat(parent.aCommonName().toString()).isEqualTo("a");
+    assertThat(parent.newChildComponent().aCommonName().toString()).isEqualTo("a");
+    assertThat(parent.newChildComponent().bCommonName().toString()).isEqualTo("1");
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/subcomponent/repeat/RepeatedModuleTest.java b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/repeat/RepeatedModuleTest.java
new file mode 100644
index 0000000..7e92371
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/subcomponent/repeat/RepeatedModuleTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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 test.subcomponent.repeat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public final class RepeatedModuleTest {
+  private ParentComponent parentComponent;
+
+  @Before
+  public void initializeParentComponent() {
+    this.parentComponent = DaggerParentComponent.builder().build();
+  }
+
+  @Test
+  public void repeatedModuleHasSameStateInSubcomponent() {
+    SubcomponentWithRepeatedModule childComponent =
+        parentComponent.newChildComponentBuilder().build();
+    assertThat(parentComponent.state()).isSameAs(childComponent.state());
+  }
+
+  @Test
+  public void repeatedModuleHasSameStateInGrandchildSubcomponent() {
+    SubcomponentWithoutRepeatedModule childComponent =
+        parentComponent.newChildComponentWithoutRepeatedModule();
+    SubcomponentWithRepeatedModule grandchildComponent =
+        childComponent.newGrandchildBuilder().build();
+    assertThat(parentComponent.state()).isSameAs(grandchildComponent.state());
+  }
+
+  @Test
+  public void repeatedModuleBuilderThrowsInSubcomponent() {
+    SubcomponentWithRepeatedModule.Builder childComponentBuilder =
+        parentComponent.newChildComponentBuilder();
+    try {
+      childComponentBuilder.repeatedModule(new RepeatedModule());
+      fail();
+    } catch (UnsupportedOperationException expected) {
+      assertThat(expected)
+          .hasMessage(
+              "test.subcomponent.repeat.RepeatedModule cannot be set "
+                  + "because it is inherited from the enclosing component");
+    }
+  }
+
+  @Test
+  public void repeatedModuleBuilderThrowsInGrandchildSubcomponent() {
+    SubcomponentWithoutRepeatedModule childComponent =
+        parentComponent.newChildComponentWithoutRepeatedModule();
+    SubcomponentWithRepeatedModule.Builder grandchildComponentBuilder =
+        childComponent.newGrandchildBuilder();
+    try {
+      grandchildComponentBuilder.repeatedModule(new RepeatedModule());
+      fail();
+    } catch (UnsupportedOperationException expected) {
+      assertThat(expected)
+          .hasMessage(
+              "test.subcomponent.repeat.RepeatedModule cannot be set "
+                  + "because it is inherited from the enclosing component");
+    }
+  }
+}
diff --git a/compiler/src/it/functional-tests/src/test/java/test/tck/TckTest.java b/compiler/src/it/functional-tests/src/test/java/test/tck/TckTest.java
new file mode 100644
index 0000000..d79b06b
--- /dev/null
+++ b/compiler/src/it/functional-tests/src/test/java/test/tck/TckTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 test.tck;
+
+import junit.framework.Test;
+import org.atinject.tck.Tck;
+import org.atinject.tck.auto.Car;
+import org.atinject.tck.auto.Convertible;
+
+/** 
+ * Test suite to execute the JSR-330 TCK in JUnit.
+ */
+public class TckTest {
+  public static Test suite() {
+    CarShop carShopComponent = DaggerCarShop.create();
+    Car car = carShopComponent.make();
+    Convertible.localConvertible.set((Convertible) car);
+    return Tck.testsFor(car, false, false);
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/pom.xml b/compiler/src/it/producers-functional-tests/pom.xml
new file mode 100644
index 0000000..a0d1649
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2014 Google, Inc.
+
+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.
+-->
+<project
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+  <groupId>dagger.tests</groupId>
+  <artifactId>producers-functional-tests</artifactId>
+  <name>Producers Functional Tests</name>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-producers</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.1</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.10</version>
+        <configuration>
+          <failsOnError>false</failsOnError>
+          <consoleOutput>true</consoleOutput>
+          <configLocation>../../../../checkstyle.xml</configLocation>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedComponent.java
new file mode 100644
index 0000000..a80ea49
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedComponent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Component;
+
+@Component(modules = DependedModule.class)
+interface DependedComponent {
+  String getGreeting();
+}
+
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedModule.java
new file mode 100644
index 0000000..dc62612
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class DependedModule {
+  @Provides
+  String provideGreeting() {
+    return "Hello world!";
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProducerModule.java
new file mode 100644
index 0000000..fe47c99
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProducerModule.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.base.Ascii;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+
+import java.util.List;
+
+@ProducerModule
+final class DependedProducerModule {
+
+  @Produces
+  int produceNumberOfGreetings() {
+    return 2;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProductionComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProductionComponent.java
new file mode 100644
index 0000000..ba98e36
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependedProductionComponent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+
+@ProductionComponent(modules = DependedProducerModule.class)
+interface DependedProductionComponent {
+  ListenableFuture<Integer> numGreetings();
+}
+
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentComponent.java
new file mode 100644
index 0000000..85709f0
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentComponent.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+
+import java.util.List;
+
+@ProductionComponent(
+    modules = DependentProducerModule.class,
+    dependencies = {DependedComponent.class, DependedProductionComponent.class})
+interface DependentComponent {
+  ListenableFuture<List<String>> greetings();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentProducerModule.java
new file mode 100644
index 0000000..e16c822
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/DependentProducerModule.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.base.Ascii;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+
+import java.util.List;
+
+@ProducerModule
+final class DependentProducerModule {
+  @Produces
+  ListenableFuture<List<String>> greetings(Integer numGreetings, String greeting) {
+    List<String> greetings = ImmutableList.of(
+        String.valueOf(numGreetings), greeting, Ascii.toUpperCase(greeting));
+    return Futures.immediateFuture(greetings);
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingComponent.java
new file mode 100644
index 0000000..6277e62
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingComponent.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Produced;
+import dagger.producers.ProductionComponent;
+import java.util.Set;
+import producerstest.MultibindingProducerModule.PossiblyThrowingSet;
+
+@ProductionComponent(modules = MultibindingProducerModule.class)
+interface MultibindingComponent {
+  ListenableFuture<Set<String>> strs();
+  ListenableFuture<Integer> strCount();
+
+  ListenableFuture<Set<Produced<String>>> successfulSet();
+
+  @PossiblyThrowingSet
+  ListenableFuture<Set<Produced<String>>> possiblyThrowingSet();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingProducerModule.java
new file mode 100644
index 0000000..09cd5bd
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/MultibindingProducerModule.java
@@ -0,0 +1,76 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.util.Set;
+import javax.inject.Qualifier;
+
+import static dagger.producers.Produces.Type.SET;
+import static dagger.producers.Produces.Type.SET_VALUES;
+
+@ProducerModule
+final class MultibindingProducerModule {
+  @Qualifier
+  @interface PossiblyThrowingSet {}
+
+  @Produces(type = SET)
+  static ListenableFuture<String> futureStr() {
+    return Futures.immediateFuture("foo");
+  }
+
+  @Produces(type = SET)
+  static String str() {
+    return "bar";
+  }
+
+  @Produces(type = SET_VALUES)
+  static ListenableFuture<Set<String>> futureStrs() {
+    return Futures.<Set<String>>immediateFuture(ImmutableSet.of("foo1", "foo2"));
+  }
+
+  @Produces(type = SET_VALUES)
+  static Set<String> strs() {
+    return ImmutableSet.of("bar1", "bar2");
+  }
+
+  @Produces
+  static int strCount(Set<String> strs) {
+    return strs.size();
+  }
+
+  @Produces(type = SET)
+  @PossiblyThrowingSet
+  static String successfulStringForSet() {
+    return "singleton";
+  }
+
+  @Produces(type = SET_VALUES)
+  @PossiblyThrowingSet
+  static Set<String> successfulStringsForSet() {
+    return ImmutableSet.of("double", "ton");
+  }
+
+  @Produces(type = SET)
+  @PossiblyThrowingSet
+  static String throwingStringForSet() {
+    throw new RuntimeException("monkey");
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Request.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Request.java
new file mode 100644
index 0000000..0227be6
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Request.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import javax.inject.Inject;
+
+final class Request {
+  private final String name;
+
+  @Inject
+  Request() {
+    this.name = "Request";
+  }
+
+  String name() {
+    return this.name;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Response.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Response.java
new file mode 100644
index 0000000..8618ff5
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/Response.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+final class Response {
+  private final String data;
+
+  Response(String data) {
+    this.data = data;
+  }
+
+  String data() {
+    return this.data;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseModule.java
new file mode 100644
index 0000000..1edbe8a
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class ResponseModule {
+  @Provides
+  static int requestNumber() {
+    return 5;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseProducerModule.java
new file mode 100644
index 0000000..0ef2ae8
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/ResponseProducerModule.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+
+@ProducerModule(includes = ResponseModule.class)
+final class ResponseProducerModule {
+  @Produces
+  static ListenableFuture<String> greeting() {
+    return Futures.immediateFuture("Hello");
+  }
+
+  @Produces
+  static Response response(String greeting, Request request, int requestNumber) {
+    return new Response(String.format("%s, %s #%d!", greeting, request.name(), requestNumber));
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleComponent.java
new file mode 100644
index 0000000..1d1e492
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleComponent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+
+@ProductionComponent(modules = ResponseProducerModule.class)
+interface SimpleComponent {
+  ListenableFuture<Response> response();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleProducerModule.java
new file mode 100644
index 0000000..2d831ed
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/SimpleProducerModule.java
@@ -0,0 +1,219 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.io.IOException;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.inject.Qualifier;
+
+import static dagger.producers.Produces.Type.SET;
+import static dagger.producers.Produces.Type.SET_VALUES;
+
+/**
+ * A module that contains various signatures of produces methods. This is not used in any
+ * components.
+ */
+@ProducerModule
+final class SimpleProducerModule {
+  @Qualifier @interface Qual {
+    int value();
+  }
+
+  // Unique bindings.
+
+  @Produces
+  @Qual(-2)
+  static ListenableFuture<String> throwingProducer() {
+    throw new RuntimeException("monkey");
+  }
+
+  @Produces
+  @Qual(-1)
+  static ListenableFuture<String> settableFutureStr(SettableFuture<String> future) {
+    return future;
+  }
+
+  @Produces
+  @Qual(0)
+  static String str() {
+    return "str";
+  }
+
+  @Produces
+  @Qual(1)
+  static ListenableFuture<String> futureStr() {
+    return Futures.immediateFuture("future str");
+  }
+
+  @Produces
+  @Qual(2)
+  static String strWithArg(int i) {
+    return "str with arg";
+  }
+
+  @Produces
+  @Qual(3)
+  static ListenableFuture<String> futureStrWithArg(int i) {
+    return Futures.immediateFuture("future str with arg");
+  }
+
+  @Produces
+  @Qual(4)
+  static String strThrowingException() throws IOException {
+    return "str throwing exception";
+  }
+
+  @Produces
+  @Qual(5)
+  static ListenableFuture<String> futureStrThrowingException() throws IOException {
+    return Futures.immediateFuture("future str throwing exception");
+  }
+
+  @Produces
+  @Qual(6)
+  static String strWithArgThrowingException(int i) throws IOException {
+    return "str with arg throwing exception";
+  }
+
+  @Produces
+  @Qual(7)
+  static ListenableFuture<String> futureStrWithArgThrowingException(int i) throws IOException {
+    return Futures.immediateFuture("future str with arg throwing exception");
+  }
+
+  @Produces
+  @Qual(8)
+  static String strWithArgs(int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) {
+    return "str with args";
+  }
+
+  @Produces
+  @Qual(9)
+  static String strWithArgsThrowingException(
+      int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) throws IOException {
+    return "str with args throwing exception";
+  }
+
+  @Produces
+  @Qual(10)
+  static ListenableFuture<String> futureStrWithArgs(
+      int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) {
+    return Futures.immediateFuture("future str with args");
+  }
+
+  @Produces
+  @Qual(11)
+  static ListenableFuture<String> futureStrWithArgsThrowingException(
+      int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) throws IOException {
+    return Futures.immediateFuture("str with args throwing exception");
+  }
+
+  // Set bindings.
+
+  @Produces(type = SET)
+  static String setOfStrElement() {
+    return "set of str element";
+  }
+
+  @Produces(type = SET)
+  static String setOfStrElementThrowingException() throws IOException {
+    return "set of str element throwing exception";
+  }
+
+  @Produces(type = SET)
+  static ListenableFuture<String> setOfStrFutureElement() {
+    return Futures.immediateFuture("set of str element");
+  }
+
+  @Produces(type = SET)
+  static ListenableFuture<String> setOfStrFutureElementThrowingException() throws IOException {
+    return Futures.immediateFuture("set of str element throwing exception");
+  }
+
+  @Produces(type = SET)
+  static String setOfStrElementWithArg(int i) {
+    return "set of str element with arg";
+  }
+
+  @Produces(type = SET)
+  static String setOfStrElementWithArgThrowingException(int i) throws IOException {
+    return "set of str element with arg throwing exception";
+  }
+
+  @Produces(type = SET)
+  static ListenableFuture<String> setOfStrFutureElementWithArg(int i) {
+    return Futures.immediateFuture("set of str element with arg");
+  }
+
+  @Produces(type = SET)
+  static ListenableFuture<String> setOfStrFutureElementWithArgThrowingException(int i)
+      throws IOException {
+    return Futures.immediateFuture("set of str element with arg throwing exception");
+  }
+
+  @Produces(type = SET_VALUES)
+  static Set<String> setOfStrValues() {
+    return ImmutableSet.of("set of str 1", "set of str 2");
+  }
+
+  @Produces(type = SET_VALUES)
+  static Set<String> setOfStrValuesThrowingException() throws IOException {
+    return ImmutableSet.of("set of str 1", "set of str 2 throwing exception");
+  }
+
+  @Produces(type = SET_VALUES)
+  static ListenableFuture<Set<String>> setOfStrFutureValues() {
+    return Futures.<Set<String>>immediateFuture(ImmutableSet.of("set of str 1", "set of str 2"));
+  }
+
+  @Produces(type = SET_VALUES)
+  static ListenableFuture<Set<String>> setOfStrFutureValuesThrowingException() throws IOException {
+    return Futures.<Set<String>>immediateFuture(
+        ImmutableSet.of("set of str 1", "set of str 2 throwing exception"));
+  }
+
+  @Produces(type = SET_VALUES)
+  static Set<String> setOfStrValuesWithArg(int i) {
+    return ImmutableSet.of("set of str with arg 1", "set of str with arg 2");
+  }
+
+  @Produces(type = SET_VALUES)
+  static Set<String> setOfStrValuesWithArgThrowingException(int i) throws IOException {
+    return ImmutableSet.of("set of str with arg 1", "set of str with arg 2 throwing exception");
+  }
+
+  @Produces(type = SET_VALUES)
+  static ListenableFuture<Set<String>> setOfStrFutureValuesWithArg(int i) {
+    return Futures.<Set<String>>immediateFuture(
+        ImmutableSet.of("set of str with arg 1", "set of str with arg 2"));
+  }
+
+  @Produces(type = SET_VALUES)
+  static ListenableFuture<Set<String>> setOfStrFutureValuesWithArgThrowingException(int i)
+      throws IOException {
+    return Futures.<Set<String>>immediateFuture(
+        ImmutableSet.of("set of str with arg 1", "set of str with arg 2 throwing exception"));
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/ComponentDependency.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/ComponentDependency.java
new file mode 100644
index 0000000..7bba4ea
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/ComponentDependency.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.badexecutor;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+interface ComponentDependency {
+  ListenableFuture<Double> doubleDep();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleComponent.java
new file mode 100644
index 0000000..6b3536e
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.badexecutor;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+
+/**
+ * A component that contains entry points that exercise different execution paths, for verifying the
+ * behavior when the executor throws a {@link java.util.concurrent.RejectedExecutionException}.
+ */
+@ProductionComponent(dependencies = ComponentDependency.class, modules = SimpleProducerModule.class)
+interface SimpleComponent {
+  /** An entry point exposing a producer method with no args. */
+  ListenableFuture<String> noArgStr();
+
+  /** An entry point exposing a producer method that depends on another producer method. */
+  ListenableFuture<Integer> singleArgInt();
+
+  /** An entry point exposing a producer method that depends on a component dependency method. */
+  ListenableFuture<Boolean> singleArgBool();
+
+  /** An entry point exposing a component dependency method. */
+  ListenableFuture<Double> doubleDep();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleProducerModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleProducerModule.java
new file mode 100644
index 0000000..00ab037
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/badexecutor/SimpleProducerModule.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.badexecutor;
+
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+
+@ProducerModule
+final class SimpleProducerModule {
+  @Produces
+  static String noArgStr() {
+    return "no arg string";
+  }
+
+  @Produces
+  static int singleArgInt(String arg) {
+    return arg.length();
+  }
+
+  @Produces
+  static boolean singleArgBool(double arg) {
+    return arg > 0.0;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/DepComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/DepComponent.java
new file mode 100644
index 0000000..dadde7b
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/DepComponent.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.builder;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+interface DepComponent {
+  ListenableFuture<Double> d();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/IntModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/IntModule.java
new file mode 100644
index 0000000..7f99836
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/IntModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.builder;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class IntModule {
+  @Provides
+  static int i() {
+    return 42;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/StringModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/StringModule.java
new file mode 100644
index 0000000..cdf0793
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/StringModule.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.builder;
+
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+
+@ProducerModule
+final class StringModule {
+  @Produces
+  static String str(int i) {
+    return "arg: " + i;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/TestComponentWithBuilder.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/TestComponentWithBuilder.java
new file mode 100644
index 0000000..16dc9ba
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/builder/TestComponentWithBuilder.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.builder;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+import java.util.concurrent.Executor;
+
+@ProductionComponent(
+  modules = {StringModule.class, IntModule.class},
+  dependencies = DepComponent.class
+)
+interface TestComponentWithBuilder {
+  ListenableFuture<String> s();
+  ListenableFuture<Double> d();
+
+  @ProductionComponent.Builder
+  interface Builder {
+    Builder depComponent(DepComponent depComponent);
+    Builder strModule(StringModule strModule);
+    Builder executor(Executor executor);
+    TestComponentWithBuilder build();
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoredComponent.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoredComponent.java
new file mode 100644
index 0000000..48acbab
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoredComponent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProductionComponent;
+
+@ProductionComponent(modules = {MonitoringModule.class, StubModule.class, ServingModule.class})
+interface MonitoredComponent {
+  ListenableFuture<String> output();
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoringModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoringModule.java
new file mode 100644
index 0000000..0c42090
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/MonitoringModule.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+
+import static dagger.Provides.Type.SET;
+
+@Module
+final class MonitoringModule {
+  private final ProductionComponentMonitor.Factory monitorFactory;
+
+  MonitoringModule(ProductionComponentMonitor.Factory monitorFactory) {
+    this.monitorFactory = monitorFactory;
+  }
+
+  @Provides(type = SET)
+  ProductionComponentMonitor.Factory monitorFactory() {
+    return monitorFactory;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/ServingModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/ServingModule.java
new file mode 100644
index 0000000..d5bec22
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/ServingModule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import javax.inject.Qualifier;
+import producerstest.monitoring.StubModule.ForServer1;
+import producerstest.monitoring.StubModule.ForServer2;
+
+@ProducerModule
+final class ServingModule {
+  @Qualifier
+  @interface RequestData {}
+
+  @Qualifier
+  @interface IntermediateData {}
+
+  @Produces
+  @RequestData
+  static String requestData() {
+    return "Hello, World!";
+  }
+
+  @Produces
+  @IntermediateData
+  static ListenableFuture<String> callServer1(
+      @RequestData String data, @ForServer1 StringStub stub) {
+    return stub.run(data);
+  }
+
+  @Produces
+  static ListenableFuture<String> callServer2(
+      @IntermediateData String data, @ForServer2 StringStub stub) {
+    return stub.run(data);
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StringStub.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StringStub.java
new file mode 100644
index 0000000..195dd28
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StringStub.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+interface StringStub {
+  ListenableFuture<String> run(String input);
+}
diff --git a/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StubModule.java b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StubModule.java
new file mode 100644
index 0000000..dc8ab62
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/main/java/producerstest/monitoring/StubModule.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Qualifier;
+
+@Module
+final class StubModule {
+  @Qualifier
+  @interface ForServer1 {}
+
+  @Qualifier
+  @interface ForServer2 {}
+
+  private final StringStub server1;
+  private final StringStub server2;
+
+  StubModule(StringStub server1, StringStub server2) {
+    this.server1 = server1;
+    this.server2 = server2;
+  }
+
+  @Provides
+  @ForServer1
+  StringStub server1() {
+    return server1;
+  }
+
+  @Provides
+  @ForServer2
+  StringStub server2() {
+    return server2;
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/DependentTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/DependentTest.java
new file mode 100644
index 0000000..b2533d7
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/DependentTest.java
@@ -0,0 +1,74 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class DependentTest {
+  @Test public void dependentComponent() throws Exception {
+    DependentComponent dependentComponent = DaggerDependentComponent
+        .builder()
+        .dependedProductionComponent(DaggerDependedProductionComponent.builder()
+            .executor(MoreExecutors.directExecutor())
+            .build())
+        .dependedComponent(DaggerDependedComponent.create())
+        .executor(MoreExecutors.directExecutor())
+        .build();
+    assertThat(dependentComponent).isNotNull();
+    assertThat(dependentComponent.greetings().get()).containsExactly(
+        "2", "Hello world!", "HELLO WORLD!");
+  }
+
+  @Test public void reuseBuilderWithDependentComponent() throws Exception {
+    DaggerDependentComponent.Builder dependentComponentBuilder = DaggerDependentComponent
+        .builder()
+        .executor(MoreExecutors.directExecutor());
+
+    DependentComponent componentUsingComponents = dependentComponentBuilder
+        .dependedProductionComponent(DaggerDependedProductionComponent.builder()
+            .executor(MoreExecutors.directExecutor())
+            .build())
+        .dependedComponent(DaggerDependedComponent.create())
+        .build();
+
+    DependentComponent componentUsingJavaImpls = dependentComponentBuilder
+        .dependedProductionComponent(new DependedProductionComponent() {
+          @Override public ListenableFuture<Integer> numGreetings() {
+            return Futures.immediateFuture(3);
+          }
+        })
+        .dependedComponent(new DependedComponent() {
+          @Override public String getGreeting() {
+            return "Goodbye world!";
+          }
+        })
+        .build();
+
+    assertThat(componentUsingJavaImpls.greetings().get()).containsExactly(
+        "3", "Goodbye world!", "GOODBYE WORLD!");
+    assertThat(componentUsingComponents.greetings().get()).containsExactly(
+        "2", "Hello world!", "HELLO WORLD!");
+
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/MultibindingTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/MultibindingTest.java
new file mode 100644
index 0000000..4ddc7c6
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/MultibindingTest.java
@@ -0,0 +1,73 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.MoreExecutors;
+import dagger.producers.Produced;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class MultibindingTest {
+  @Test
+  public void setBinding() throws Exception {
+    MultibindingComponent multibindingComponent =
+        DaggerMultibindingComponent.builder().executor(MoreExecutors.directExecutor()).build();
+    assertThat(multibindingComponent.strs().get())
+        .containsExactly("foo", "foo1", "foo2", "bar", "bar1", "bar2");
+    assertThat(multibindingComponent.strCount().get()).isEqualTo(6);
+  }
+
+  @Test
+  public void setBindingOfProduced() throws Exception {
+    MultibindingComponent multibindingComponent =
+        DaggerMultibindingComponent.builder().executor(MoreExecutors.directExecutor()).build();
+    assertThat(multibindingComponent.successfulSet().get())
+        .containsExactly(
+            Produced.successful("foo"),
+            Produced.successful("foo1"),
+            Produced.successful("foo2"),
+            Produced.successful("bar"),
+            Produced.successful("bar1"),
+            Produced.successful("bar2"));
+  }
+
+  @Test
+  public void setBindingOfProducedWithFailures() throws Exception {
+    MultibindingComponent multibindingComponent =
+        DaggerMultibindingComponent.builder().executor(MoreExecutors.directExecutor()).build();
+    Set<Produced<String>> possiblyThrowingSet = multibindingComponent.possiblyThrowingSet().get();
+    Set<String> successes = new HashSet<>();
+    Set<ExecutionException> failures = new HashSet<>();
+    for (Produced<String> str : possiblyThrowingSet) {
+      try {
+        successes.add(str.get());
+      } catch (ExecutionException e) {
+        failures.add(e);
+      }
+    }
+    assertThat(successes).containsExactly("singleton", "double", "ton");
+    assertThat(failures).hasSize(1);
+    assertThat(Iterables.getOnlyElement(failures).getCause()).hasMessage("monkey");
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/ProducerFactoryTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/ProducerFactoryTest.java
new file mode 100644
index 0000000..9a56029
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/ProducerFactoryTest.java
@@ -0,0 +1,185 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.SettableFuture;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import java.util.concurrent.ExecutionException;
+import javax.inject.Provider;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.when;
+
+@RunWith(JUnit4.class)
+public class ProducerFactoryTest {
+  @Mock private ProductionComponentMonitor componentMonitor;
+  private ProducerMonitor monitor;
+  private Provider<ProductionComponentMonitor> componentMonitorProvider;
+
+  @Before
+  public void setUpMocks() {
+    MockitoAnnotations.initMocks(this);
+    monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS);
+    when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor);
+    componentMonitorProvider =
+        new Provider<ProductionComponentMonitor>() {
+          @Override
+          public ProductionComponentMonitor get() {
+            return componentMonitor;
+          }
+        };
+  }
+
+  @Test
+  public void noArgMethod() throws Exception {
+    ProducerToken token = ProducerToken.create(SimpleProducerModule_StrFactory.class);
+    Producer<String> producer =
+        new SimpleProducerModule_StrFactory(
+            MoreExecutors.directExecutor(), componentMonitorProvider);
+    assertThat(producer.get().get()).isEqualTo("str");
+    InOrder order = inOrder(componentMonitor, monitor);
+    order.verify(componentMonitor).producerMonitorFor(token);
+    order.verify(monitor).methodStarting();
+    order.verify(monitor).methodFinished();
+    order.verify(monitor).succeeded("str");
+    order.verifyNoMoreInteractions();
+  }
+
+  @Test public void singleArgMethod() throws Exception {
+    SettableFuture<Integer> intFuture = SettableFuture.create();
+    Producer<Integer> intProducer = producerOfFuture(intFuture);
+    Producer<String> producer =
+        new SimpleProducerModule_StrWithArgFactory(
+            MoreExecutors.directExecutor(), componentMonitorProvider, intProducer);
+    assertThat(producer.get().isDone()).isFalse();
+    intFuture.set(42);
+    assertThat(producer.get().get()).isEqualTo("str with arg");
+  }
+
+  @Test
+  public void successMonitor() throws Exception {
+    ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
+
+    SettableFuture<String> strFuture = SettableFuture.create();
+    SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
+    Producer<SettableFuture<String>> strFutureProducer = producerOfFuture(strFutureFuture);
+    Producer<String> producer =
+        new SimpleProducerModule_SettableFutureStrFactory(
+            MoreExecutors.directExecutor(), componentMonitorProvider, strFutureProducer);
+    assertThat(producer.get().isDone()).isFalse();
+
+    InOrder order = inOrder(componentMonitor, monitor);
+    order.verify(componentMonitor).producerMonitorFor(token);
+
+    strFutureFuture.set(strFuture);
+    order.verify(monitor).methodStarting();
+    order.verify(monitor).methodFinished();
+    assertThat(producer.get().isDone()).isFalse();
+
+    strFuture.set("monkey");
+    assertThat(producer.get().get()).isEqualTo("monkey");
+    order.verify(monitor).succeeded("monkey");
+
+    order.verifyNoMoreInteractions();
+  }
+
+  @Test
+  public void failureMonitor() throws Exception {
+    ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
+
+    SettableFuture<String> strFuture = SettableFuture.create();
+    SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
+    Producer<SettableFuture<String>> strFutureProducer = producerOfFuture(strFutureFuture);
+    Producer<String> producer =
+        new SimpleProducerModule_SettableFutureStrFactory(
+            MoreExecutors.directExecutor(), componentMonitorProvider, strFutureProducer);
+    assertThat(producer.get().isDone()).isFalse();
+
+    InOrder order = inOrder(componentMonitor, monitor);
+    order.verify(componentMonitor).producerMonitorFor(token);
+
+    strFutureFuture.set(strFuture);
+    order.verify(monitor).methodStarting();
+    order.verify(monitor).methodFinished();
+    assertThat(producer.get().isDone()).isFalse();
+
+    Throwable t = new RuntimeException("monkey");
+    strFuture.setException(t);
+    try {
+      producer.get().get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isSameAs(t);
+      order.verify(monitor).failed(t);
+    }
+
+    order.verifyNoMoreInteractions();
+  }
+
+  @Test
+  public void failureMonitorDueToThrowingProducer() throws Exception {
+    ProducerToken token = ProducerToken.create(SimpleProducerModule_ThrowingProducerFactory.class);
+
+    Producer<String> producer =
+        new SimpleProducerModule_ThrowingProducerFactory(
+            MoreExecutors.directExecutor(), componentMonitorProvider);
+    assertThat(producer.get().isDone()).isTrue();
+
+    InOrder order = inOrder(componentMonitor, monitor);
+    order.verify(componentMonitor).producerMonitorFor(token);
+
+    order.verify(monitor).methodStarting();
+    order.verify(monitor).methodFinished();
+
+    try {
+      producer.get().get();
+      fail();
+    } catch (ExecutionException e) {
+      order.verify(monitor).failed(e.getCause());
+    }
+
+    order.verifyNoMoreInteractions();
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void nullComponentMonitorProvider() throws Exception {
+    new SimpleProducerModule_StrFactory(MoreExecutors.directExecutor(), null);
+  }
+
+  private static <T> Producer<T> producerOfFuture(final ListenableFuture<T> future) {
+    return new Producer<T>() {
+      @Override public ListenableFuture<T> get() {
+        return future;
+      }
+    };
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/SimpleTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/SimpleTest.java
new file mode 100644
index 0000000..cacc0f1
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/SimpleTest.java
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 producerstest;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class SimpleTest {
+  @Test public void testSimpleComponent() throws Exception {
+    SimpleComponent simpleComponent = DaggerSimpleComponent
+        .builder()
+        .executor(MoreExecutors.directExecutor())
+        .build();
+    assertThat(simpleComponent).isNotNull();
+    assertThat(simpleComponent.response().get().data()).isEqualTo("Hello, Request #5!");
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/badexecutor/BadExecutorTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/badexecutor/BadExecutorTest.java
new file mode 100644
index 0000000..8a49797
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/badexecutor/BadExecutorTest.java
@@ -0,0 +1,74 @@
+package producerstest.badexecutor;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RejectedExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+/** This test verifies behavior when the executor throws {@link RejectedExecutionException}. */
+@RunWith(JUnit4.class)
+public final class BadExecutorTest {
+  private SimpleComponent component;
+
+  @Before
+  public void setUpComponent() {
+    ComponentDependency dependency =
+        new ComponentDependency() {
+          @Override
+          public ListenableFuture<Double> doubleDep() {
+            return Futures.immediateFuture(42.0);
+          }
+        };
+    ListeningExecutorService executorService = MoreExecutors.newDirectExecutorService();
+    component =
+        DaggerSimpleComponent.builder()
+            .executor(executorService)
+            .componentDependency(dependency)
+            .build();
+    executorService.shutdown();
+  }
+
+  @Test
+  public void rejectNoArgMethod() throws Exception {
+    try {
+      component.noArgStr().get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isInstanceOf(RejectedExecutionException.class);
+    }
+  }
+
+  @Test
+  public void rejectSingleArgMethod() throws Exception {
+    try {
+      component.singleArgInt().get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isInstanceOf(RejectedExecutionException.class);
+    }
+  }
+
+  @Test
+  public void rejectSingleArgFromComponentDepMethod() throws Exception {
+    try {
+      component.singleArgBool().get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isInstanceOf(RejectedExecutionException.class);
+    }
+  }
+
+  @Test
+  public void doNotRejectComponentDepMethod() throws Exception {
+    assertThat(component.doubleDep().get()).isEqualTo(42.0);
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/builder/ProductionComponentBuilderTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/builder/ProductionComponentBuilderTest.java
new file mode 100644
index 0000000..715761d
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/builder/ProductionComponentBuilderTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.builder;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+/** Tests for {@link dagger.producers.ProductionComponent.Builder}. */
+@RunWith(JUnit4.class)
+public final class ProductionComponentBuilderTest {
+
+  @Test
+  public void successfulBuild() throws Exception {
+    TestComponentWithBuilder component =
+        DaggerTestComponentWithBuilder.builder()
+            .executor(MoreExecutors.directExecutor())
+            .depComponent(depComponent(15.3))
+            .strModule(new StringModule())
+            .build();
+    assertThat(component.s().get()).isEqualTo("arg: 42");
+    assertThat(component.d().get()).isEqualTo(15.3);
+  }
+
+  @Test
+  public void successfulBuild_withMissingZeroArgModule() throws Exception {
+    TestComponentWithBuilder component =
+        DaggerTestComponentWithBuilder.builder()
+            .executor(MoreExecutors.directExecutor())
+            .depComponent(depComponent(15.3))
+            .build();
+    assertThat(component.s().get()).isEqualTo("arg: 42");
+    assertThat(component.d().get()).isEqualTo(15.3);
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void missingExecutor() {
+    DaggerTestComponentWithBuilder.builder()
+        .depComponent(depComponent(15.3))
+        .strModule(new StringModule())
+        .build();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void missingDepComponent() {
+    DaggerTestComponentWithBuilder.builder()
+        .executor(MoreExecutors.directExecutor())
+        .strModule(new StringModule())
+        .build();
+  }
+
+  private static DepComponent depComponent(final double value) {
+    return new DepComponent() {
+      @Override
+      public ListenableFuture<Double> d() {
+        return Futures.immediateFuture(value);
+      }
+    };
+  }
+}
diff --git a/compiler/src/it/producers-functional-tests/src/test/java/producerstest/monitoring/MonitoringTest.java b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/monitoring/MonitoringTest.java
new file mode 100644
index 0000000..3efb2b5
--- /dev/null
+++ b/compiler/src/it/producers-functional-tests/src/test/java/producerstest/monitoring/MonitoringTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 producerstest.monitoring;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.SettableFuture;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/** Tests for production components using monitoring. */
+@RunWith(JUnit4.class)
+public final class MonitoringTest {
+  @Mock private ProductionComponentMonitor.Factory componentMonitorFactory;
+  @Mock private StringStub server1;
+  @Mock private StringStub server2;
+  private SettableFuture<String> server1Future;
+  private SettableFuture<String> server2Future;
+  private FakeProductionComponentMonitor componentMonitor;
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+    componentMonitor = new FakeProductionComponentMonitor();
+    when(componentMonitorFactory.create(any())).thenReturn(componentMonitor);
+    server1Future = SettableFuture.create();
+    server2Future = SettableFuture.create();
+    when(server1.run(any(String.class))).thenReturn(server1Future);
+    when(server2.run(any(String.class))).thenReturn(server2Future);
+  }
+
+  @Test
+  public void basicMonitoring() throws Exception {
+    MonitoredComponent component =
+        DaggerMonitoredComponent.builder()
+            .executor(MoreExecutors.directExecutor())
+            .monitoringModule(new MonitoringModule(componentMonitorFactory))
+            .stubModule(new StubModule(server1, server2))
+            .build();
+    ListenableFuture<String> output = component.output();
+    assertThat(componentMonitor.monitors).hasSize(3);
+    ImmutableList<Map.Entry<ProducerToken, ProducerMonitor>> entries =
+        ImmutableList.copyOf(componentMonitor.monitors.entrySet());
+    assertThat(entries.get(0).getKey().toString()).contains("CallServer2");
+    assertThat(entries.get(1).getKey().toString()).contains("CallServer1");
+    assertThat(entries.get(2).getKey().toString()).contains("RequestData");
+
+    ProducerMonitor callServer2Monitor = entries.get(0).getValue();
+    ProducerMonitor callServer1Monitor = entries.get(1).getValue();
+    ProducerMonitor requestDataMonitor = entries.get(2).getValue();
+
+    InOrder inOrder = inOrder(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+    inOrder.verify(requestDataMonitor).methodStarting();
+    inOrder.verify(requestDataMonitor).methodFinished();
+    inOrder.verify(requestDataMonitor).succeeded("Hello, World!");
+    inOrder.verify(callServer1Monitor).methodStarting();
+    inOrder.verify(callServer1Monitor).methodFinished();
+    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+
+    server1Future.set("server 1 response");
+    inOrder.verify(callServer1Monitor).succeeded("server 1 response");
+    inOrder.verify(callServer2Monitor).methodStarting();
+    inOrder.verify(callServer2Monitor).methodFinished();
+    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+
+    server2Future.set("server 2 response");
+    inOrder.verify(callServer2Monitor).succeeded("server 2 response");
+    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+    assertThat(output.get()).isEqualTo("server 2 response");
+  }
+
+  @Test
+  public void basicMonitoringWithFailure() throws Exception {
+    MonitoredComponent component =
+        DaggerMonitoredComponent.builder()
+            .executor(MoreExecutors.directExecutor())
+            .monitoringModule(new MonitoringModule(componentMonitorFactory))
+            .stubModule(new StubModule(server1, server2))
+            .build();
+    ListenableFuture<String> output = component.output();
+    assertThat(componentMonitor.monitors).hasSize(3);
+    ImmutableList<Map.Entry<ProducerToken, ProducerMonitor>> entries =
+        ImmutableList.copyOf(componentMonitor.monitors.entrySet());
+    assertThat(entries.get(0).getKey().toString()).contains("CallServer2");
+    assertThat(entries.get(1).getKey().toString()).contains("CallServer1");
+    assertThat(entries.get(2).getKey().toString()).contains("RequestData");
+
+    ProducerMonitor callServer2Monitor = entries.get(0).getValue();
+    ProducerMonitor callServer1Monitor = entries.get(1).getValue();
+    ProducerMonitor requestDataMonitor = entries.get(2).getValue();
+
+    InOrder inOrder = inOrder(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+    inOrder.verify(requestDataMonitor).methodStarting();
+    inOrder.verify(requestDataMonitor).methodFinished();
+    inOrder.verify(requestDataMonitor).succeeded("Hello, World!");
+    inOrder.verify(callServer1Monitor).methodStarting();
+    inOrder.verify(callServer1Monitor).methodFinished();
+    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+
+    RuntimeException cause = new RuntimeException("monkey");
+    server1Future.setException(cause);
+    inOrder.verify(callServer1Monitor).failed(cause);
+    inOrder.verify(callServer2Monitor).failed(any(Throwable.class));
+    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
+    try {
+      output.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(Throwables.getRootCause(e)).isSameAs(cause);
+    }
+  }
+
+  private static final class FakeProductionComponentMonitor implements ProductionComponentMonitor {
+    final Map<ProducerToken, ProducerMonitor> monitors = new LinkedHashMap<>();
+
+    @Override
+    public ProducerMonitor producerMonitorFor(ProducerToken token) {
+      ProducerMonitor monitor = mock(ProducerMonitor.class);
+      monitors.put(token, monitor);
+      return monitor;
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/AbstractComponentProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentProcessingStep.java
new file mode 100644
index 0000000..578fb5f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentProcessingStep.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.auto.common.MoreElements;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import java.lang.annotation.Annotation;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * A {@link ProcessingStep} that is responsible for dealing with a component or production component
+ * as part of the {@link ComponentProcessor}.
+ */
+abstract class AbstractComponentProcessingStep implements ProcessingStep {
+
+  private final Class<? extends Annotation> componentAnnotation;
+  private final Messager messager;
+  private final ComponentHierarchyValidator componentHierarchyValidator;
+  private final BindingGraphValidator bindingGraphValidator;
+  private final ComponentDescriptor.Factory componentDescriptorFactory;
+  private final BindingGraph.Factory bindingGraphFactory;
+  private final ComponentGenerator componentGenerator;
+
+  AbstractComponentProcessingStep(
+      Class<? extends Annotation> componentAnnotation,
+      Messager messager,
+      ComponentHierarchyValidator componentHierarchyValidator,
+      BindingGraphValidator bindingGraphValidator,
+      ComponentDescriptor.Factory componentDescriptorFactory,
+      BindingGraph.Factory bindingGraphFactory,
+      ComponentGenerator componentGenerator) {
+    this.componentAnnotation = componentAnnotation;
+    this.messager = messager;
+    this.componentHierarchyValidator = componentHierarchyValidator;
+    this.bindingGraphValidator = bindingGraphValidator;
+    this.componentDescriptorFactory = componentDescriptorFactory;
+    this.bindingGraphFactory = bindingGraphFactory;
+    this.componentGenerator = componentGenerator;
+  }
+
+  @Override
+  public final ImmutableSet<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    ImmutableSet.Builder<Element> rejectedElements = ImmutableSet.builder();
+    ComponentElementValidator componentElementValidator =
+        componentElementValidator(elementsByAnnotation);
+    for (Element element : elementsByAnnotation.get(componentAnnotation)) {
+      TypeElement componentTypeElement = MoreElements.asType(element);
+      try {
+        if (componentElementValidator.validateComponent(componentTypeElement, messager)) {
+          ComponentDescriptor componentDescriptor =
+              componentDescriptorFactory.forComponent(componentTypeElement);
+          ValidationReport<TypeElement> hierarchyReport =
+              componentHierarchyValidator.validate(componentDescriptor);
+          hierarchyReport.printMessagesTo(messager);
+          if (hierarchyReport.isClean()) {
+            BindingGraph bindingGraph = bindingGraphFactory.create(componentDescriptor);
+            ValidationReport<TypeElement> graphReport =
+                bindingGraphValidator.validate(bindingGraph);
+            graphReport.printMessagesTo(messager);
+            if (graphReport.isClean()) {
+              generateComponent(bindingGraph);
+            }
+          }
+        }
+      } catch (TypeNotPresentException e) {
+        rejectedElements.add(componentTypeElement);
+      }
+    }
+    return rejectedElements.build();
+  }
+
+  private void generateComponent(BindingGraph bindingGraph) {
+    try {
+      componentGenerator.generate(bindingGraph);
+    } catch (SourceFileGenerationException e) {
+      e.printMessageTo(messager);
+    }
+  }
+
+  /**
+   * Returns an object that can validate a type element annotated with the component type.
+   */
+  protected abstract ComponentElementValidator componentElementValidator(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation);
+
+  /**
+   * Validates a component type element.
+   */
+  protected static abstract class ComponentElementValidator {
+    /**
+     * Validates a component type element. Prints any messages about the element to
+     * {@code messager}.
+     *
+     * @throws TypeNotPresentException if any type required to validate the component cannot be
+     *     found
+     */
+    abstract boolean validateComponent(TypeElement componentTypeElement, Messager messager);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java
new file mode 100644
index 0000000..db890b2
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java
@@ -0,0 +1,1165 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.MembersInjector;
+import dagger.internal.DelegateFactory;
+import dagger.internal.Factory;
+import dagger.internal.InstanceFactory;
+import dagger.internal.MapFactory;
+import dagger.internal.MapProviderFactory;
+import dagger.internal.MembersInjectors;
+import dagger.internal.ScopedProvider;
+import dagger.internal.SetFactory;
+import dagger.internal.codegen.ComponentDescriptor.BuilderSpec;
+import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
+import dagger.internal.codegen.ComponentGenerator.MemberSelect;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.ConstructorWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.StringLiteral;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import dagger.internal.codegen.writer.VoidName;
+import dagger.producers.Producer;
+import dagger.producers.internal.Producers;
+import dagger.producers.internal.SetOfProducedProducer;
+import dagger.producers.internal.SetProducer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+
+import static com.google.auto.common.MoreTypes.asDeclared;
+import static com.google.common.base.CaseFormat.LOWER_CAMEL;
+import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static dagger.internal.codegen.AbstractComponentWriter.InitializationState.DELEGATED;
+import static dagger.internal.codegen.AbstractComponentWriter.InitializationState.INITIALIZED;
+import static dagger.internal.codegen.AbstractComponentWriter.InitializationState.UNINITIALIZED;
+import static dagger.internal.codegen.Binding.bindingPackageFor;
+import static dagger.internal.codegen.ComponentGenerator.MemberSelect.staticMethodInvocationWithCast;
+import static dagger.internal.codegen.ComponentGenerator.MemberSelect.staticSelect;
+import static dagger.internal.codegen.ContributionBinding.contributionTypeFor;
+import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.ENUM_INSTANCE;
+import static dagger.internal.codegen.ContributionBinding.Kind.PROVISION;
+import static dagger.internal.codegen.ErrorMessages.CANNOT_RETURN_NULL_FROM_NON_NULLABLE_COMPONENT_METHOD;
+import static dagger.internal.codegen.MapKeys.getMapKeySnippet;
+import static dagger.internal.codegen.MembersInjectionBinding.Strategy.NO_OP;
+import static dagger.internal.codegen.SourceFiles.frameworkTypeUsageStatement;
+import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
+import static dagger.internal.codegen.SourceFiles.indexDependenciesByUnresolvedKey;
+import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
+import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
+import static dagger.internal.codegen.Util.getKeyTypeOfMap;
+import static dagger.internal.codegen.Util.getProvidedValueTypeOfMap;
+import static dagger.internal.codegen.Util.isMapWithNonProvidedValues;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+import static dagger.internal.codegen.writer.Snippet.memberSelectSnippet;
+import static dagger.internal.codegen.writer.Snippet.nullCheck;
+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;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.VOID;
+
+/**
+ * Creates the implementation class for a component or subcomponent.
+ */
+abstract class AbstractComponentWriter {
+  // TODO(dpb): Make all these fields private after refactoring is complete.
+  protected final Elements elements;
+  protected final Types types;
+  protected final Key.Factory keyFactory;
+  protected final Kind nullableValidationType;
+  protected final Set<JavaWriter> javaWriters = new LinkedHashSet<>();
+  protected final ClassName name;
+  protected final BindingGraph graph;
+  private final Map<BindingKey, InitializationState> initializationStates = new HashMap<>();
+  private final Map<Binding, InitializationState> contributionInitializationStates =
+      new HashMap<>();
+  protected ClassWriter componentWriter;
+  private final Map<BindingKey, MemberSelect> memberSelectSnippets = new HashMap<>();
+  private final Map<ContributionBinding, MemberSelect> multibindingContributionSnippets =
+      new HashMap<>();
+  protected ConstructorWriter constructorWriter;
+  protected Optional<ClassName> builderName = Optional.absent();
+
+  /**
+   * For each component requirement, the builder field. This map is empty for subcomponents that do
+   * not use a builder.
+   */
+  private ImmutableMap<TypeElement, FieldWriter> builderFields = ImmutableMap.of();
+
+  /**
+   * For each component requirement, the snippet for the component field that holds it.
+   *
+   * <p>Fields are written for all requirements for subcomponents that do not use a builder, and for
+   * any requirement that is reused from a subcomponent of this component.
+   */
+  protected final Map<TypeElement, MemberSelect> componentContributionFields = Maps.newHashMap();
+
+  AbstractComponentWriter(
+      Types types,
+      Elements elements,
+      Key.Factory keyFactory,
+      Diagnostic.Kind nullableValidationType,
+      ClassName name,
+      BindingGraph graph) {
+    this.types = types;
+    this.elements = elements;
+    this.keyFactory = keyFactory;
+    this.nullableValidationType = nullableValidationType;
+    this.name = name;
+    this.graph = graph;
+  }
+
+  protected final TypeElement componentDefinitionType() {
+    return graph.componentDescriptor().componentDefinitionType();
+  }
+
+  protected final ClassName componentDefinitionTypeName() {
+    return ClassName.fromTypeElement(componentDefinitionType());
+  }
+
+  /**
+   * Returns an expression snippet that evaluates to an instance of the contribution, looking for
+   * either a builder field or a component field.
+   */
+  private Snippet getComponentContributionSnippet(TypeElement contributionType) {
+    if (builderFields.containsKey(contributionType)) {
+      return Snippet.format("builder.%s", builderFields.get(contributionType).name());
+    } else {
+      Optional<Snippet> snippet = getOrCreateComponentContributionFieldSnippet(contributionType);
+      checkState(snippet.isPresent(), "no builder or component field for %s", contributionType);
+      return snippet.get();
+    }
+  }
+
+  /**
+   * Returns a snippet for a component contribution field. Adds a field the first time one is
+   * requested for a contribution type if this component's builder has a field for it.
+   */
+  protected Optional<Snippet> getOrCreateComponentContributionFieldSnippet(
+      TypeElement contributionType) {
+    MemberSelect fieldSelect = componentContributionFields.get(contributionType);
+    if (fieldSelect == null) {
+      if (!builderFields.containsKey(contributionType)) {
+        return Optional.absent();
+      }
+      FieldWriter componentField =
+          componentWriter.addField(contributionType, simpleVariableName(contributionType));
+      componentField.addModifiers(PRIVATE, FINAL);
+      constructorWriter
+          .body()
+          .addSnippet(
+              "this.%s = builder.%s;",
+              componentField.name(),
+              builderFields.get(contributionType).name());
+      fieldSelect = MemberSelect.instanceSelect(name, Snippet.format("%s", componentField.name()));
+      componentContributionFields.put(contributionType, fieldSelect);
+    }
+    return Optional.of(fieldSelect.getSnippetFor(name));
+  }
+
+  private Snippet getMemberSelectSnippet(BindingKey key) {
+    return getMemberSelect(key).getSnippetFor(name);
+  }
+
+  protected MemberSelect getMemberSelect(BindingKey key) {
+    return memberSelectSnippets.get(key);
+  }
+
+  protected Optional<MemberSelect> getMultibindingContributionSnippet(ContributionBinding binding) {
+    return Optional.fromNullable(multibindingContributionSnippets.get(binding));
+  }
+
+  /**
+   * Returns the initialization state of the factory field for a binding key in this component.
+   */
+  protected InitializationState getInitializationState(BindingKey bindingKey) {
+    return initializationStates.containsKey(bindingKey)
+        ? initializationStates.get(bindingKey)
+        : UNINITIALIZED;
+  }
+
+  private void setInitializationState(BindingKey bindingKey, InitializationState state) {
+    initializationStates.put(bindingKey, state);
+  }
+
+  private InitializationState getContributionInitializationState(Binding binding) {
+    return contributionInitializationStates.containsKey(binding)
+        ? contributionInitializationStates.get(binding)
+        : UNINITIALIZED;
+  }
+
+  private void setContributionInitializationState(Binding binding, InitializationState state) {
+    contributionInitializationStates.put(binding, state);
+  }
+
+  ImmutableSet<JavaWriter> write() {
+    if (javaWriters.isEmpty()) {
+      writeComponent();
+    }
+    return ImmutableSet.copyOf(javaWriters);
+  }
+
+  private void writeComponent() {
+    componentWriter = createComponentClass();
+    addConstructor();
+    addBuilder();
+    addFactoryMethods();
+    addFields();
+    initializeFrameworkTypes();
+    implementInterfaceMethods();
+    addSubcomponents();
+  }
+
+  /**
+   * Creates the component implementation class.
+   */
+  protected abstract ClassWriter createComponentClass();
+
+  private void addConstructor() {
+    constructorWriter = componentWriter.addConstructor();
+    constructorWriter.addModifiers(PRIVATE);
+  }
+
+  /**
+   * Adds a builder type.
+   */
+  protected void addBuilder() {
+    ClassWriter builderWriter = createBuilder();
+    builderWriter.addModifiers(FINAL);
+    builderWriter.addConstructor().addModifiers(PRIVATE);
+    builderName = Optional.of(builderWriter.name());
+
+    Optional<BuilderSpec> builderSpec = graph.componentDescriptor().builderSpec();
+    if (builderSpec.isPresent()) {
+      builderWriter.addModifiers(PRIVATE);
+      builderWriter.setSupertype(builderSpec.get().builderDefinitionType());
+    } else {
+      builderWriter.addModifiers(PUBLIC);
+    }
+
+    builderFields = addBuilderFields(builderWriter);
+    addBuildMethod(builderWriter, builderSpec);
+    addBuilderMethods(builderWriter, builderSpec);
+
+    constructorWriter.addParameter(builderWriter, "builder");
+    constructorWriter.body().addSnippet("assert builder != null;");
+  }
+
+  /**
+   * Adds fields for each of the {@linkplain BindingGraph#componentRequirements component
+   * requirements}. Regardless of builder spec, there is always one field per requirement.
+   */
+  private ImmutableMap<TypeElement, FieldWriter> addBuilderFields(ClassWriter builderWriter) {
+    ImmutableMap.Builder<TypeElement, FieldWriter> builderFieldsBuilder = ImmutableMap.builder();
+    for (TypeElement contributionElement : graph.componentRequirements()) {
+      String contributionName = simpleVariableName(contributionElement);
+      FieldWriter builderField = builderWriter.addField(contributionElement, contributionName);
+      builderField.addModifiers(PRIVATE);
+      builderFieldsBuilder.put(contributionElement, builderField);
+    }
+    return builderFieldsBuilder.build();
+  }
+
+  /** Adds the build method to the builder. */
+  private void addBuildMethod(ClassWriter builderWriter, Optional<BuilderSpec> builderSpec) {
+    MethodWriter buildMethod;
+    if (builderSpec.isPresent()) {
+      ExecutableElement specBuildMethod = builderSpec.get().buildMethod();
+      // Note: we don't use the specBuildMethod.getReturnType() as the return type
+      // because it might be a type variable.  We make use of covariant returns to allow
+      // us to return the component type, which will always be valid.
+      buildMethod =
+          builderWriter.addMethod(
+              componentDefinitionTypeName(), specBuildMethod.getSimpleName().toString());
+      buildMethod.annotate(Override.class);
+    } else {
+      buildMethod = builderWriter.addMethod(componentDefinitionTypeName(), "build");
+    }
+    buildMethod.addModifiers(PUBLIC);
+
+    for (Map.Entry<TypeElement, FieldWriter> builderFieldEntry : builderFields.entrySet()) {
+      FieldWriter builderField = builderFieldEntry.getValue();
+      if (componentCanMakeNewInstances(builderFieldEntry.getKey())) {
+        buildMethod.body()
+            .addSnippet("if (%1$s == null) { this.%1$s = new %2$s(); }",
+                builderField.name(),
+                builderField.type());
+      } else {
+        buildMethod.body()
+            .addSnippet(
+                "if (%s == null) { throw new %s(%s.class.getCanonicalName() + \" must be set\"); }",
+                builderField.name(),
+                ClassName.fromClass(IllegalStateException.class),
+                builderField.type());
+      }
+    }
+
+    buildMethod.body().addSnippet("return new %s(this);", name);
+  }
+
+  /**
+   * Adds the methods that set each of parameters on the builder. If the {@link BuilderSpec} is
+   * present, it will tailor the methods to match the spec.
+   */
+  private void addBuilderMethods(
+      ClassWriter builderWriter,
+      Optional<BuilderSpec> builderSpec) {
+    if (builderSpec.isPresent()) {
+      for (Map.Entry<TypeElement, ExecutableElement> builderMethodEntry :
+          builderSpec.get().methodMap().entrySet()) {
+        TypeElement builderMethodType = builderMethodEntry.getKey();
+        ExecutableElement specMethod = builderMethodEntry.getValue();
+        MethodWriter builderMethod = addBuilderMethodFromSpec(builderWriter, specMethod);
+        String parameterName =
+            Iterables.getOnlyElement(specMethod.getParameters()).getSimpleName().toString();
+        builderMethod.addParameter(builderMethodType, parameterName);
+        builderMethod.body().addSnippet(nullCheck(parameterName));
+        if (graph.componentRequirements().contains(builderMethodType)) {
+          // required type
+          builderMethod.body().addSnippet("this.%s = %s;",
+              builderFields.get(builderMethodType).name(),
+              parameterName);
+          addBuilderMethodReturnStatementForSpec(specMethod, builderMethod);
+        } else if (graph.ownedModuleTypes().contains(builderMethodType)) {
+          // owned, but not required
+          builderMethod.body()
+              .addSnippet("// This module is declared, but not used in the component. "
+                  + "This method is a no-op");
+          addBuilderMethodReturnStatementForSpec(specMethod, builderMethod);
+        } else {
+          // neither owned nor required, so it must be an inherited module
+          builderMethod
+              .body()
+              .addSnippet(
+                  "throw new %s(%s.format(%s, %s.class.getCanonicalName()));",
+                  ClassName.fromClass(UnsupportedOperationException.class),
+                  ClassName.fromClass(String.class),
+                  StringLiteral.forValue(
+                      "%s cannot be set because it is inherited from the enclosing component"),
+                  ClassName.fromTypeElement(builderMethodType));
+        }
+      }
+    } else {
+      for (TypeElement componentRequirement : graph.availableDependencies()) {
+        String componentRequirementName = simpleVariableName(componentRequirement);
+        MethodWriter builderMethod = builderWriter.addMethod(
+            builderWriter.name(),
+            componentRequirementName);
+        builderMethod.addModifiers(PUBLIC);
+        builderMethod.addParameter(componentRequirement, componentRequirementName);
+        builderMethod.body().addSnippet(nullCheck(componentRequirementName));
+        if (graph.componentRequirements().contains(componentRequirement)) {
+          builderMethod.body()
+              .addSnippet("this.%s = %s;",
+                  builderFields.get(componentRequirement).name(),
+                  componentRequirementName);
+        } else {
+          builderMethod.annotate(Deprecated.class);
+        }
+        builderMethod.body().addSnippet("return this;");
+      }
+    }
+  }
+
+  private void addBuilderMethodReturnStatementForSpec(
+      ExecutableElement specMethod, MethodWriter builderMethod) {
+    if (!specMethod.getReturnType().getKind().equals(VOID)) {
+      builderMethod.body().addSnippet("return this;");
+    }
+  }
+
+  private MethodWriter addBuilderMethodFromSpec(
+      ClassWriter builderWriter, ExecutableElement method) {
+    String methodName = method.getSimpleName().toString();
+    TypeMirror returnType = method.getReturnType();
+    // If the return type is void, we add a method with the void return type.
+    // Otherwise we use the builderWriter and take advantage of covariant returns
+    // (so that we don't have to worry about setter methods that return type variables).
+    MethodWriter builderMethod =
+        returnType.getKind().equals(TypeKind.VOID)
+            ? builderWriter.addMethod(returnType, methodName)
+            : builderWriter.addMethod(builderWriter, methodName);
+    builderMethod.annotate(Override.class);
+    builderMethod.addModifiers(Sets.difference(method.getModifiers(), ImmutableSet.of(ABSTRACT)));
+    return builderMethod;
+  }
+
+  /**
+   * Creates the builder class.
+   */
+  protected abstract ClassWriter createBuilder();
+
+  /**
+   * Adds component factory methods.
+   */
+  protected abstract void addFactoryMethods();
+
+  private void addFields() {
+    for (ResolvedBindings resolvedBindings : graph.resolvedBindings().values()) {
+      addField(resolvedBindings);
+    }
+  }
+
+  private void addField(ResolvedBindings resolvedBindings) {
+    BindingKey bindingKey = resolvedBindings.bindingKey();
+
+    // No field needed if there are no owned bindings.
+    if (resolvedBindings.ownedBindings().isEmpty()) {
+      return;
+    }
+    
+    // No field needed for bindings with no dependencies or state.
+    Optional<MemberSelect> staticMemberSelect = staticMemberSelect(resolvedBindings);
+    if (staticMemberSelect.isPresent()) {
+      memberSelectSnippets.put(bindingKey, staticMemberSelect.get());
+      return;
+    }
+
+    Optional<String> bindingPackage = bindingPackageFor(resolvedBindings.bindings());
+    boolean useRawType = bindingPackage.isPresent()
+        && !bindingPackage.get().equals(name.packageName());
+    if (bindingKey.kind().equals(BindingKey.Kind.CONTRIBUTION)) {
+      ImmutableSet<ContributionBinding> contributionBindings =
+          resolvedBindings.contributionBindings();
+      if (ContributionBinding.contributionTypeFor(contributionBindings).isMultibinding()) {
+        // note that here we rely on the order of the resolved bindings being from parent to child
+        // otherwise, the numbering wouldn't work
+        int contributionNumber = 0;
+        for (ContributionBinding contributionBinding : contributionBindings) {
+          if (!contributionBinding.isSyntheticBinding()) {
+            contributionNumber++;
+            if (resolvedBindings.ownedContributionBindings().contains(contributionBinding)) {
+              FrameworkField contributionBindingField =
+                  FrameworkField.createForSyntheticContributionBinding(
+                      contributionNumber, contributionBinding);
+              FieldWriter contributionField =
+                  addFrameworkField(useRawType, contributionBindingField);
+
+              ImmutableList<String> contributionSelectTokens =
+                  new ImmutableList.Builder<String>()
+                      .add(contributionField.name())
+                      .build();
+              multibindingContributionSnippets.put(
+                  contributionBinding,
+                  MemberSelect.instanceSelect(name, memberSelectSnippet(contributionSelectTokens)));
+            }
+          }
+        }
+      }
+    }
+
+    FrameworkField bindingField = FrameworkField.createForResolvedBindings(resolvedBindings);
+    FieldWriter frameworkField = addFrameworkField(useRawType, bindingField);
+
+    ImmutableList<String> memberSelectTokens =
+        new ImmutableList.Builder<String>()
+            .add(frameworkField.name())
+            .build();
+    memberSelectSnippets.put(
+        bindingKey,
+        MemberSelect.instanceSelect(name, Snippet.memberSelectSnippet(memberSelectTokens)));
+  }
+
+  private FieldWriter addFrameworkField(boolean useRawType,
+      FrameworkField contributionBindingField) {
+    FieldWriter contributionField =
+        componentWriter.addField(
+            useRawType
+                ? contributionBindingField.frameworkType().type()
+                : contributionBindingField.frameworkType(),
+            contributionBindingField.name());
+    contributionField.addModifiers(PRIVATE);
+    if (useRawType) {
+      contributionField.annotate(SuppressWarnings.class).setValue("rawtypes");
+    }
+    return contributionField;
+  }
+
+  /**
+   * If {@code resolvedBindings} is an unscoped provision binding with no factory arguments or a
+   * no-op members injection binding, then we don't need a field to hold its factory. In that case,
+   * this method returns the static member select snippet that returns the factory or no-op members
+   * injector.
+   */
+  private Optional<MemberSelect> staticMemberSelect(ResolvedBindings resolvedBindings) {
+    switch (resolvedBindings.bindingKey().kind()) {
+      case CONTRIBUTION:
+        if (resolvedBindings.contributionBindings().size() != 1) {
+          return Optional.absent();
+        }
+        ContributionBinding contributionBinding =
+            getOnlyElement(resolvedBindings.contributionBindings());
+        if (contributionBinding.contributionType().isMultibinding()
+            || !(contributionBinding.bindingType().equals(Binding.Type.PROVISION))) {
+          return Optional.absent();
+        }
+        if (contributionBinding.factoryCreationStrategy().equals(ENUM_INSTANCE)
+            && !contributionBinding.scope().isPresent()) {
+          return Optional.of(
+              staticSelect(
+                  generatedClassNameForBinding(contributionBinding), Snippet.format("create()")));
+        }
+        break;
+
+      case MEMBERS_INJECTION:
+        Optional<MembersInjectionBinding> membersInjectionBinding =
+            resolvedBindings.membersInjectionBinding();
+        if (membersInjectionBinding.isPresent()
+            && membersInjectionBinding.get().injectionStrategy().equals(NO_OP)) {
+          return Optional.of(
+              staticMethodInvocationWithCast(
+                  ClassName.fromClass(MembersInjectors.class),
+                  Snippet.format("noOp()"),
+                  ClassName.fromClass(MembersInjector.class)));
+        }
+        break;
+
+      default:
+        throw new AssertionError();
+    }
+    return Optional.absent();
+  }
+
+  private void implementInterfaceMethods() {
+    Set<MethodSignature> interfaceMethods = Sets.newHashSet();
+    for (ComponentMethodDescriptor componentMethod :
+        graph.componentDescriptor().componentMethods()) {
+      if (componentMethod.dependencyRequest().isPresent()) {
+        DependencyRequest interfaceRequest = componentMethod.dependencyRequest().get();
+        ExecutableElement requestElement =
+            MoreElements.asExecutable(interfaceRequest.requestElement());
+        ExecutableType requestType = MoreTypes.asExecutable(types.asMemberOf(
+            MoreTypes.asDeclared(componentDefinitionType().asType()), requestElement));
+        MethodSignature signature = MethodSignature.fromExecutableType(
+            requestElement.getSimpleName().toString(), requestType);
+        if (!interfaceMethods.contains(signature)) {
+          interfaceMethods.add(signature);
+          MethodWriter interfaceMethod =
+              requestType.getReturnType().getKind().equals(VOID)
+                  ? componentWriter.addMethod(
+                      VoidName.VOID, requestElement.getSimpleName().toString())
+                  : componentWriter.addMethod(
+                      requestType.getReturnType(), requestElement.getSimpleName().toString());
+          interfaceMethod.annotate(Override.class);
+          interfaceMethod.addModifiers(PUBLIC);
+          BindingKey bindingKey = interfaceRequest.bindingKey();
+          MemberSelect memberSelect = getMemberSelect(bindingKey);
+          Snippet memberSelectSnippet = memberSelect.getSnippetFor(name);
+          switch (interfaceRequest.kind()) {
+            case MEMBERS_INJECTOR:
+              List<? extends VariableElement> parameters = requestElement.getParameters();
+              if (parameters.isEmpty()) {
+                // we're returning the framework type
+                interfaceMethod.body().addSnippet("return %s;", memberSelectSnippet);
+              } else {
+                VariableElement parameter = Iterables.getOnlyElement(parameters);
+                Name parameterName = parameter.getSimpleName();
+                interfaceMethod.addParameter(
+                    TypeNames.forTypeMirror(
+                        Iterables.getOnlyElement(requestType.getParameterTypes())),
+                    parameterName.toString());
+                interfaceMethod
+                    .body()
+                    .addSnippet(
+                        "%s.injectMembers(%s);",
+                        memberSelectSnippet,
+                        parameterName);
+                if (!requestType.getReturnType().getKind().equals(VOID)) {
+                  interfaceMethod.body().addSnippet("return %s;", parameterName);
+                }
+              }
+              break;
+            case INSTANCE:
+              if (memberSelect.staticMember()
+                  && bindingKey.key().type().getKind().equals(DECLARED)
+                  && !((DeclaredType) bindingKey.key().type()).getTypeArguments().isEmpty()) {
+                // If using a parameterized enum type, then we need to store the factory
+                // in a temporary variable, in order to help javac be able to infer
+                // the generics of the Factory.create methods.
+                TypeName factoryType =
+                    ParameterizedTypeName.create(
+                        Provider.class, TypeNames.forTypeMirror(requestType.getReturnType()));
+                interfaceMethod
+                    .body()
+                    .addSnippet(
+                        "%s factory = %s;", factoryType, memberSelectSnippet);
+                interfaceMethod.body().addSnippet("return factory.get();");
+                break;
+              }
+              // fall through in the else case.
+            case LAZY:
+            case PRODUCED:
+            case PRODUCER:
+            case PROVIDER:
+            case FUTURE:
+              interfaceMethod
+                  .body()
+                  .addSnippet(
+                      "return %s;",
+                      frameworkTypeUsageStatement(
+                          memberSelectSnippet, interfaceRequest.kind()));
+              break;
+            default:
+              throw new AssertionError();
+          }
+        }
+      }
+    }
+  }
+
+  private void addSubcomponents() {
+    for (Map.Entry<ExecutableElement, BindingGraph> subgraphEntry : graph.subgraphs().entrySet()) {
+      SubcomponentWriter subcomponent =
+          new SubcomponentWriter(this, subgraphEntry.getKey(), subgraphEntry.getValue());
+      javaWriters.addAll(subcomponent.write());
+    }
+  }
+
+  private static final int SNIPPETS_PER_INITIALIZATION_METHOD = 100;
+
+  private void initializeFrameworkTypes() {
+    ImmutableList.Builder<Snippet> snippetsBuilder = ImmutableList.builder();
+    for (BindingKey bindingKey : graph.resolvedBindings().keySet()) {
+      snippetsBuilder.add(initializeFrameworkType(bindingKey));
+    }
+    ImmutableList<Snippet> snippets = snippetsBuilder.build();
+
+    List<List<Snippet>> partitions = Lists.partition(snippets, SNIPPETS_PER_INITIALIZATION_METHOD);
+    for (int i = 0; i < partitions.size(); i++) {
+      MethodWriter initializeMethod =
+          componentWriter.addMethod(VoidName.VOID, "initialize" + ((i == 0) ? "" : i));
+      /* TODO(gak): Strictly speaking, we only need the suppression here if we are also initializing
+       * a raw field in this method, but the structure of this code makes it awkward to pass that
+       * bit through.  This will be cleaned up when we no longer separate fields and initilization
+       * as we do now. */
+      initializeMethod.annotate(SuppressWarnings.class).setValue("unchecked");
+      for (Snippet snippet : partitions.get(i)) {
+        initializeMethod.body().addSnippet(snippet);
+      }
+      initializeMethod.addModifiers(PRIVATE);
+      if (builderName.isPresent()) {
+        initializeMethod.addParameter(builderName.get(), "builder").addModifiers(FINAL);
+        constructorWriter.body().addSnippet("%s(builder);", initializeMethod.name());
+      } else {
+        constructorWriter.body().addSnippet("%s();", initializeMethod.name());
+      }
+    }
+  }
+
+  /**
+   * Returns a single snippet representing the initialization of the framework type.
+   *
+   * <p>Note that this must be a single snippet because initialization snippets can be invoked from
+   * any place in any order.  By requiring a single snippet (often of concatenated snippets) we
+   * ensure that things like local variables always behave as expected by the initialization logic.
+   */
+  private Snippet initializeFrameworkType(BindingKey bindingKey) {
+    ResolvedBindings resolvedBindings = graph.resolvedBindings().get(bindingKey);
+    
+    // There's no field for inherited bindings.
+    if (resolvedBindings.ownedBindings().isEmpty()) {
+      return Snippet.format("");
+    }
+    
+    switch (bindingKey.kind()) {
+      case CONTRIBUTION:
+        switch (contributionTypeFor(resolvedBindings.contributionBindings())) {
+          case SET:
+            return initializeSetMultibindings(resolvedBindings);
+          case MAP:
+            return initializeMapMultibindings(resolvedBindings);
+          case UNIQUE:
+            return initializeUniqueContributionBinding(resolvedBindings);
+          default:
+            throw new AssertionError();
+        }
+
+      case MEMBERS_INJECTION:
+        return initializeMembersInjectionBinding(resolvedBindings);
+
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private Snippet initializeSetMultibindings(ResolvedBindings resolvedBindings) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    ImmutableList.Builder<Snippet> parameterSnippets = ImmutableList.builder();
+    for (ContributionBinding binding : resolvedBindings.contributionBindings()) {
+      Optional<MemberSelect> multibindingContributionSnippet =
+          getMultibindingContributionSnippet(binding);
+      checkState(multibindingContributionSnippet.isPresent(), "%s was not found", binding);
+      Snippet snippet = multibindingContributionSnippet.get().getSnippetFor(name);
+      if (multibindingContributionSnippet.get().owningClass().equals(name)
+          // the binding might already be initialized by a different set binding that shares the
+          // same contributions (e.g., Set<T> and Set<Produced<T>>)
+          && getContributionInitializationState(binding)
+              .equals(InitializationState.UNINITIALIZED)) {
+        Snippet initializeSnippet = initializeFactoryForContributionBinding(binding);
+        initializationSnippets.add(Snippet.format("this.%s = %s;", snippet, initializeSnippet));
+        setContributionInitializationState(binding, InitializationState.INITIALIZED);
+      }
+      parameterSnippets.add(snippet);
+    }
+    Class<?> factoryClass =
+        Iterables.all(resolvedBindings.contributionBindings(), Binding.Type.PROVISION)
+            ? SetFactory.class
+            : Util.isSetOfProduced(resolvedBindings.bindingKey().key().type())
+                ? SetOfProducedProducer.class
+                : SetProducer.class;
+    Snippet initializeSetSnippet =
+        Snippet.format(
+            "%s.create(%s)",
+            ClassName.fromClass(factoryClass),
+            makeParametersSnippet(parameterSnippets.build()));
+    initializationSnippets.add(
+        initializeMember(resolvedBindings.bindingKey(), initializeSetSnippet));
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet initializeMapMultibindings(ResolvedBindings resolvedBindings) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    if (any(resolvedBindings.contributionBindings(), Binding.Type.PRODUCTION)) {
+      // TODO(beder): Implement producer map bindings.
+      throw new IllegalStateException("producer map bindings not implemented yet");
+    }
+    for (ContributionBinding binding : resolvedBindings.contributionBindings()) {
+      Optional<MemberSelect> multibindingContributionSnippet =
+          getMultibindingContributionSnippet(binding);
+      if (!isMapWithNonProvidedValues(binding.key().type())
+          && multibindingContributionSnippet.isPresent()
+          && multibindingContributionSnippet.get().owningClass().equals(name)) {
+        initializationSnippets.add(
+            Snippet.format(
+                "this.%s = %s;",
+                multibindingContributionSnippet.get().getSnippetFor(name),
+                initializeFactoryForContributionBinding(binding)));
+      }
+    }
+    initializationSnippets.add(
+        initializeMember(
+            resolvedBindings.bindingKey(),
+            initializeMapBinding(resolvedBindings.contributionBindings())));
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet initializeUniqueContributionBinding(ResolvedBindings resolvedBindings) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    ContributionBinding binding = getOnlyElement(resolvedBindings.ownedContributionBindings());
+    if (!binding.factoryCreationStrategy().equals(ENUM_INSTANCE) || binding.scope().isPresent()) {
+      initializationSnippets.add(initializeDelegateFactories(binding));
+      initializationSnippets.add(
+          initializeMember(
+              resolvedBindings.bindingKey(), initializeFactoryForContributionBinding(binding)));
+    }
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet initializeMembersInjectionBinding(ResolvedBindings resolvedBindings) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    MembersInjectionBinding binding = resolvedBindings.membersInjectionBinding().get();
+    if (!binding.injectionStrategy().equals(MembersInjectionBinding.Strategy.NO_OP)) {
+      initializationSnippets.add(initializeDelegateFactories(binding));
+      initializationSnippets.add(
+          initializeMember(
+              resolvedBindings.bindingKey(), initializeMembersInjectorForBinding(binding)));
+    }
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet initializeDelegateFactories(Binding binding) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    for (Collection<DependencyRequest> requestsForKey :
+        indexDependenciesByUnresolvedKey(types, binding.dependencies()).asMap().values()) {
+      BindingKey dependencyKey =
+          Iterables.getOnlyElement(
+              FluentIterable.from(requestsForKey)
+                  .transform(DependencyRequest.BINDING_KEY_FUNCTION)
+                  .toSet());
+      if (!getMemberSelect(dependencyKey).staticMember()
+          && getInitializationState(dependencyKey).equals(UNINITIALIZED)) {
+        initializationSnippets.add(
+            Snippet.format(
+                "this.%s = new %s();",
+                getMemberSelectSnippet(dependencyKey),
+                ClassName.fromClass(DelegateFactory.class)));
+        setInitializationState(dependencyKey, DELEGATED);
+      }
+    }
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet initializeMember(BindingKey bindingKey, Snippet initializationSnippet) {
+    ImmutableList.Builder<Snippet> initializationSnippets = ImmutableList.builder();
+
+    Snippet memberSelect = getMemberSelectSnippet(bindingKey);
+    Snippet delegateFactoryVariable = delegateFactoryVariableSnippet(bindingKey);
+    if (getInitializationState(bindingKey).equals(DELEGATED)) {
+      initializationSnippets.add(
+          Snippet.format(
+              "%1$s %2$s = (%1$s) %3$s;",
+              ClassName.fromClass(DelegateFactory.class),
+              delegateFactoryVariable,
+              memberSelect));
+    }
+    initializationSnippets.add(
+        Snippet.format("this.%s = %s;", memberSelect, initializationSnippet));
+    if (getInitializationState(bindingKey).equals(DELEGATED)) {
+      initializationSnippets.add(
+          Snippet.format("%s.setDelegatedProvider(%s);", delegateFactoryVariable, memberSelect));
+    }
+    setInitializationState(bindingKey, INITIALIZED);
+
+    return Snippet.concat(initializationSnippets.build());
+  }
+
+  private Snippet delegateFactoryVariableSnippet(BindingKey key) {
+    return Snippet.format("%sDelegate", getMemberSelectSnippet(key).toString().replace('.', '_'));
+  }
+
+  private Snippet initializeFactoryForContributionBinding(ContributionBinding binding) {
+    TypeName bindingKeyTypeName = TypeNames.forTypeMirror(binding.key().type());
+    switch (binding.bindingKind()) {
+      case COMPONENT:
+        return Snippet.format(
+            "%s.<%s>create(%s)",
+            ClassName.fromClass(InstanceFactory.class),
+            bindingKeyTypeName,
+            bindingKeyTypeName.equals(componentDefinitionTypeName())
+                ? "this"
+                : getComponentContributionSnippet(MoreTypes.asTypeElement(binding.key().type())));
+
+      case COMPONENT_PROVISION:
+        {
+          TypeElement bindingTypeElement =
+              graph.componentDescriptor().dependencyMethodIndex().get(binding.bindingElement());
+          String localFactoryVariable = simpleVariableName(bindingTypeElement);
+          Snippet callFactoryMethodSnippet =
+              Snippet.format(
+                  "%s.%s()",
+                  localFactoryVariable,
+                  binding.bindingElement().getSimpleName().toString());
+          // TODO(sameb): This throws a very vague NPE right now.  The stack trace doesn't
+          // help to figure out what the method or return type is.  If we include a string
+          // of the return type or method name in the error message, that can defeat obfuscation.
+          // We can easily include the raw type (no generics) + annotation type (no values),
+          // using .class & String.format -- but that wouldn't be the whole story.
+          // What should we do?
+          StringLiteral failMsg =
+              StringLiteral.forValue(CANNOT_RETURN_NULL_FROM_NON_NULLABLE_COMPONENT_METHOD);
+          Snippet getMethodBody =
+              binding.nullableType().isPresent()
+                      || nullableValidationType.equals(Diagnostic.Kind.WARNING)
+                  ? Snippet.format("return %s;", callFactoryMethodSnippet)
+                  : Snippet.format(
+                      Joiner.on('\n')
+                          .join(
+                              "%s provided = %s;",
+                              "if (provided == null) {",
+                              "  throw new NullPointerException(%s);",
+                              "}",
+                              "return provided;"),
+                      bindingKeyTypeName,
+                      callFactoryMethodSnippet,
+                      failMsg);
+          return Snippet.format(
+              Joiner.on('\n')
+                  .join(
+                      "new %1$s<%2$s>() {",
+                      "  private final %5$s %6$s = %3$s;",
+                      "  %4$s@Override public %2$s get() {",
+                      "    %7$s",
+                      "  }",
+                      "}"),
+              /* 1 */ ClassName.fromClass(Factory.class),
+              /* 2 */ bindingKeyTypeName,
+              /* 3 */ getComponentContributionSnippet(bindingTypeElement),
+              /* 4 */ nullableSnippet(binding.nullableType()),
+              /* 5 */ TypeNames.forTypeMirror(bindingTypeElement.asType()),
+              /* 6 */ localFactoryVariable,
+              /* 7 */ getMethodBody);
+        }
+
+      case SUBCOMPONENT_BUILDER:
+        return Snippet.format(
+            Joiner.on('\n')
+                .join(
+                    "new %1$s<%2$s>() {",
+                    "  @Override public %2$s get() {",
+                    "    return %3$s();",
+                    "  }",
+                    "}"),
+            /* 1 */ ClassName.fromClass(Factory.class),
+            /* 2 */ bindingKeyTypeName,
+            /* 3 */ binding.bindingElement().getSimpleName().toString());
+        
+      case INJECTION:
+      case PROVISION:
+        {
+          List<Snippet> parameters =
+              Lists.newArrayListWithCapacity(binding.dependencies().size() + 1);
+          if (binding.bindingKind().equals(PROVISION)
+              && !binding.bindingElement().getModifiers().contains(STATIC)) {
+            parameters.add(getComponentContributionSnippet(binding.contributedBy().get()));
+          }
+          parameters.addAll(getDependencyParameters(binding));
+
+          Snippet factorySnippet =
+              Snippet.format(
+                  "%s.create(%s)",
+                  generatedClassNameForBinding(binding),
+                  Snippet.makeParametersSnippet(parameters));
+          return binding.scope().isPresent()
+              ? Snippet.format(
+                  "%s.create(%s)", ClassName.fromClass(ScopedProvider.class), factorySnippet)
+              : factorySnippet;
+        }
+
+      case COMPONENT_PRODUCTION:
+        {
+          TypeElement bindingTypeElement =
+              graph.componentDescriptor().dependencyMethodIndex().get(binding.bindingElement());
+          return Snippet.format(
+              Joiner.on('\n')
+                  .join(
+                      "new %1$s<%2$s>() {",
+                      "  private final %6$s %7$s = %4$s;",
+                      "  @Override public %3$s<%2$s> get() {",
+                      "    return %7$s.%5$s();",
+                      "  }",
+                      "}"),
+              /* 1 */ ClassName.fromClass(Producer.class),
+              /* 2 */ TypeNames.forTypeMirror(binding.key().type()),
+              /* 3 */ ClassName.fromClass(ListenableFuture.class),
+              /* 4 */ getComponentContributionSnippet(bindingTypeElement),
+              /* 5 */ binding.bindingElement().getSimpleName().toString(),
+              /* 6 */ TypeNames.forTypeMirror(bindingTypeElement.asType()),
+              /* 7 */ simpleVariableName(bindingTypeElement));
+        }
+
+      case IMMEDIATE:
+      case FUTURE_PRODUCTION:
+        {
+          List<Snippet> parameters =
+              Lists.newArrayListWithCapacity(binding.implicitDependencies().size() + 2);
+          if (!binding.bindingElement().getModifiers().contains(STATIC)) {
+            parameters.add(getComponentContributionSnippet(binding.bindingTypeElement()));
+          }
+          parameters.add(
+              getComponentContributionSnippet(
+                  graph.componentDescriptor().executorDependency().get()));
+          parameters.addAll(getProducerDependencyParameters(binding));
+
+          return Snippet.format(
+              "new %s(%s)",
+              generatedClassNameForBinding(binding),
+              Snippet.makeParametersSnippet(parameters));
+        }
+
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private Snippet nullableSnippet(Optional<DeclaredType> nullableType) {
+    return nullableType.isPresent()
+        ? Snippet.format("@%s ", TypeNames.forTypeMirror(nullableType.get()))
+        : Snippet.format("");
+  }
+
+  private Snippet initializeMembersInjectorForBinding(MembersInjectionBinding binding) {
+    switch (binding.injectionStrategy()) {
+      case NO_OP:
+        return Snippet.format("%s.noOp()", ClassName.fromClass(MembersInjectors.class));
+      case INJECT_MEMBERS:
+        List<Snippet> parameters = getDependencyParameters(binding);
+        return Snippet.format(
+            "%s.create(%s)",
+            membersInjectorNameForType(binding.bindingElement()),
+            Snippet.makeParametersSnippet(parameters));
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private List<Snippet> getDependencyParameters(Binding binding) {
+    ImmutableList.Builder<Snippet> parameters = ImmutableList.builder();
+    Set<Key> keysSeen = new HashSet<>();
+    for (Collection<DependencyRequest> requestsForKey :
+        indexDependenciesByUnresolvedKey(types, binding.implicitDependencies()).asMap().values()) {
+      Set<BindingKey> requestedBindingKeys = new HashSet<>();
+      for (DependencyRequest dependencyRequest : requestsForKey) {
+        Element requestElement = dependencyRequest.requestElement();
+        TypeMirror typeMirror = typeMirrorAsMemberOf(binding.bindingTypeElement(), requestElement);
+        Key key = keyFactory.forQualifiedType(dependencyRequest.key().qualifier(), typeMirror);
+        if (keysSeen.add(key)) {
+          requestedBindingKeys.add(dependencyRequest.bindingKey());
+        }
+      }
+      if (!requestedBindingKeys.isEmpty()) {
+        BindingKey key = Iterables.getOnlyElement(requestedBindingKeys);
+        parameters.add(getMemberSelect(key).getSnippetWithRawTypeCastFor(name));
+      }
+    }
+    return parameters.build();
+  }
+
+  // TODO(dpb): Investigate use of asMemberOf here. Why aren't the dependency requests already
+  // resolved?
+  private TypeMirror typeMirrorAsMemberOf(TypeElement bindingTypeElement, Element requestElement) {
+    TypeMirror requestType = requestElement.asType();
+    if (requestType.getKind() == TypeKind.TYPEVAR) {
+      return types.asMemberOf(
+          MoreTypes.asDeclared(bindingTypeElement.asType()),
+          (requestElement.getKind() == ElementKind.PARAMETER)
+              ? MoreTypes.asElement(requestType)
+              : requestElement);
+    } else {
+      return requestType;
+    }
+  }
+
+  private List<Snippet> getProducerDependencyParameters(Binding binding) {
+    ImmutableList.Builder<Snippet> parameters = ImmutableList.builder();
+    for (Collection<DependencyRequest> requestsForKey :
+        SourceFiles.indexDependenciesByUnresolvedKey(types, binding.implicitDependencies())
+            .asMap()
+            .values()) {
+      BindingKey key = Iterables.getOnlyElement(FluentIterable.from(requestsForKey)
+          .transform(DependencyRequest.BINDING_KEY_FUNCTION));
+      ResolvedBindings resolvedBindings = graph.resolvedBindings().get(key);
+      Class<?> frameworkClass =
+          DependencyRequestMapper.FOR_PRODUCER.getFrameworkClass(requestsForKey);
+      if (FrameworkField.frameworkClassForResolvedBindings(resolvedBindings).equals(Provider.class)
+          && frameworkClass.equals(Producer.class)) {
+        parameters.add(
+            Snippet.format(
+                "%s.producerFromProvider(%s)",
+                ClassName.fromClass(Producers.class),
+                getMemberSelectSnippet(key)));
+      } else {
+        parameters.add(getMemberSelectSnippet(key));
+      }
+    }
+    return parameters.build();
+  }
+
+  private Snippet initializeMapBinding(Set<ContributionBinding> bindings) {
+    // Get type information from the first binding.
+    ContributionBinding firstBinding = bindings.iterator().next();
+    DeclaredType mapType = asDeclared(firstBinding.key().type());
+
+    if (isMapWithNonProvidedValues(mapType)) {
+      return Snippet.format(
+          "%s.create(%s)",
+          ClassName.fromClass(MapFactory.class),
+          getMemberSelectSnippet(getOnlyElement(firstBinding.dependencies()).bindingKey()));
+    }
+
+    ImmutableList.Builder<dagger.internal.codegen.writer.Snippet> snippets =
+        ImmutableList.builder();
+    snippets.add(Snippet.format("%s.<%s, %s>builder(%d)",
+        ClassName.fromClass(MapProviderFactory.class),
+        TypeNames.forTypeMirror(getKeyTypeOfMap(mapType)),
+        TypeNames.forTypeMirror(getProvidedValueTypeOfMap(mapType)), // V of Map<K, Provider<V>>
+        bindings.size()));
+
+    for (ContributionBinding binding : bindings) {
+      snippets.add(
+          Snippet.format(
+              "    .put(%s, %s)",
+              getMapKeySnippet(binding.bindingElement()),
+              getMultibindingContributionSnippet(binding).get().getSnippetFor(name)));
+    }
+
+    snippets.add(Snippet.format("    .build()"));
+
+    return Snippet.concat(snippets.build());
+  }
+
+  private static String simpleVariableName(TypeElement typeElement) {
+    return UPPER_CAMEL.to(LOWER_CAMEL, typeElement.getSimpleName().toString());
+  }
+
+  /**
+   * Initialization state for a factory field.
+   */
+  enum InitializationState {
+    /** The field is {@code null}. */
+    UNINITIALIZED,
+
+    /** The field is set to a {@link DelegateFactory}. */
+    DELEGATED,
+
+    /** The field is set to an undelegated factory. */
+    INITIALIZED;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/Binding.java b/compiler/src/main/java/dagger/internal/codegen/Binding.java
new file mode 100644
index 0000000..0a6b840
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/Binding.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import dagger.MembersInjector;
+import dagger.producers.Producer;
+import java.util.List;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleElementVisitor6;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+/**
+ * An abstract type for classes representing a Dagger binding.  Particularly, contains the
+ * {@link Element} that generated the binding and the {@link DependencyRequest} instances that are
+ * required to satisfy the binding, but leaves the specifics of the <i>mechanism</i> of the binding
+ * to the subtypes.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+abstract class Binding {
+  
+  /**
+   * The subtype of this binding.
+   */
+  enum Type implements Predicate<Binding> {
+    /** A binding with this type is a {@link ProvisionBinding}. */
+    PROVISION(Provider.class),
+    /** A binding with this type is a {@link MembersInjectionBinding}. */
+    MEMBERS_INJECTION(MembersInjector.class),
+    /** A binding with this type is a {@link ProductionBinding}. */
+    PRODUCTION(Producer.class),
+    ;
+    
+    private final Class<?> frameworkClass;
+    
+    private Type(Class<?> frameworkClass) {
+      this.frameworkClass = frameworkClass;
+    }
+    
+    /**
+     * Returns the framework class associated with bindings of this type.
+     */
+    Class<?> frameworkClass() {
+      return frameworkClass;
+    }
+
+    BindingKey.Kind bindingKeyKind() {
+      switch (this) {
+        case MEMBERS_INJECTION:
+          return BindingKey.Kind.MEMBERS_INJECTION;
+        case PROVISION:
+        case PRODUCTION:
+          return BindingKey.Kind.CONTRIBUTION;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @Override
+    public boolean apply(Binding binding) {
+      return this.equals(binding.bindingType());
+    }
+  }
+
+  abstract Binding.Type bindingType();
+
+  /**
+   * Returns the framework class associated with this binding.
+   */
+  Class<?> frameworkClass() {
+    return bindingType().frameworkClass();
+  }
+
+  static Optional<String> bindingPackageFor(Iterable<? extends Binding> bindings) {
+    ImmutableSet.Builder<String> bindingPackagesBuilder = ImmutableSet.builder();
+    for (Binding binding : bindings) {
+      bindingPackagesBuilder.addAll(binding.bindingPackage().asSet());
+    }
+    ImmutableSet<String> bindingPackages = bindingPackagesBuilder.build();
+    switch (bindingPackages.size()) {
+      case 0:
+        return Optional.absent();
+      case 1:
+        return Optional.of(bindingPackages.iterator().next());
+      default:
+        throw new IllegalArgumentException();
+    }
+  }
+
+  /** The {@link Key} that is provided by this binding. */
+  protected abstract Key key();
+
+  BindingKey bindingKey() {
+    return BindingKey.create(bindingType().bindingKeyKind(), key());
+  }
+
+  /** Returns the {@link Element} instance that is responsible for declaring the binding. */
+  abstract Element bindingElement();
+
+  /** The type enclosing the binding {@link #bindingElement()}. */
+  TypeElement bindingTypeElement() {
+    return BINDING_TYPE_ELEMENT.visit(bindingElement());
+  }
+
+  private static final ElementVisitor<TypeElement, Void> BINDING_TYPE_ELEMENT =
+      new SimpleElementVisitor6<TypeElement, Void>() {
+        @Override
+        protected TypeElement defaultAction(Element e, Void p) {
+          return visit(e.getEnclosingElement());
+        }
+
+        @Override
+        public TypeElement visitType(TypeElement e, Void p) {
+          return e;
+        }
+      };
+
+  /**
+   * The explicit set of {@link DependencyRequest dependencies} required to satisfy this binding.
+   */
+  abstract ImmutableSet<DependencyRequest> dependencies();
+
+  /**
+   * The set of {@link DependencyRequest dependencies} required to satisfy this binding. This is a
+   * superset of {@link #dependencies()}.  This returns an unmodifiable set.
+   */
+  abstract Set<DependencyRequest> implicitDependencies();
+
+  /**
+   * Returns the name of the package in which this binding must be managed. E.g.: a binding
+   * may reference non-public types.
+   */
+  abstract Optional<String> bindingPackage();
+
+  protected static Optional<String> findBindingPackage(Key bindingKey) {
+    Set<String> packages = nonPublicPackageUse(bindingKey.type());
+    switch (packages.size()) {
+      case 0:
+        return Optional.absent();
+      case 1:
+        return Optional.of(packages.iterator().next());
+      default:
+        throw new IllegalStateException();
+    }
+  }
+
+  private static Set<String> nonPublicPackageUse(TypeMirror typeMirror) {
+    ImmutableSet.Builder<String> packages = ImmutableSet.builder();
+    typeMirror.accept(new SimpleTypeVisitor6<Void, ImmutableSet.Builder<String>>() {
+      @Override
+      public Void visitArray(ArrayType t, ImmutableSet.Builder<String> p) {
+        return t.getComponentType().accept(this, p);
+      }
+
+      @Override
+      public Void visitDeclared(DeclaredType t, ImmutableSet.Builder<String> p) {
+        for (TypeMirror typeArgument : t.getTypeArguments()) {
+          typeArgument.accept(this, p);
+        }
+        // TODO(gak): address public nested types in non-public types
+        TypeElement typeElement = MoreElements.asType(t.asElement());
+        if (!typeElement.getModifiers().contains(PUBLIC)) {
+          PackageElement elementPackage = MoreElements.getPackage(typeElement);
+          Name qualifiedName = elementPackage.getQualifiedName();
+          p.add(qualifiedName.toString());
+        }
+        // Also make sure enclosing types are visible, otherwise we're fooled by
+        // class Foo { public class Bar }
+        // (Note: we can't use t.getEnclosingType() because it doesn't work!)
+        typeElement.getEnclosingElement().asType().accept(this, p);
+        return null;
+      }
+
+      @Override
+      public Void visitWildcard(WildcardType t, ImmutableSet.Builder<String> p) {
+        if (t.getExtendsBound() != null) {
+          t.getExtendsBound().accept(this, p);
+        }
+        if (t.getSuperBound() != null) {
+          t.getSuperBound().accept(this, p);
+        }
+        return null;
+      }
+    }, packages);
+    return packages.build();
+  }
+
+  /**
+   * Returns true if this is a binding for a key that has a different type parameter list than the
+   * element it's providing.
+   */
+  abstract boolean hasNonDefaultTypeParameters();
+
+  /**
+   * The scope of this binding.
+   */
+  Scope scope() {
+    return Scope.unscoped();
+  }
+
+  // TODO(sameb): Remove the TypeElement parameter and pull it from the TypeMirror.
+  static boolean hasNonDefaultTypeParameters(TypeElement element, TypeMirror type, Types types) {
+    // If the element has no type parameters, nothing can be wrong.
+    if (element.getTypeParameters().isEmpty()) {
+      return false;
+    }
+
+    List<TypeMirror> defaultTypes = Lists.newArrayList();
+    for (TypeParameterElement parameter : element.getTypeParameters()) {
+      defaultTypes.add(parameter.asType());
+    }
+
+    List<TypeMirror> actualTypes =
+        type.accept(
+            new SimpleTypeVisitor6<List<TypeMirror>, Void>() {
+              @Override
+              protected List<TypeMirror> defaultAction(TypeMirror e, Void p) {
+                return ImmutableList.of();
+              }
+
+              @Override
+              public List<TypeMirror> visitDeclared(DeclaredType t, Void p) {
+                return ImmutableList.<TypeMirror>copyOf(t.getTypeArguments());
+              }
+            },
+            null);
+
+    // The actual type parameter size can be different if the user is using a raw type.
+    if (defaultTypes.size() != actualTypes.size()) {
+      return true;
+    }
+
+    for (int i = 0; i < defaultTypes.size(); i++) {
+      if (!types.isSameType(defaultTypes.get(i), actualTypes.get(i))) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java b/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java
new file mode 100644
index 0000000..b951438
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.TreeTraverser;
+import dagger.Component;
+import dagger.Subcomponent;
+import dagger.internal.codegen.Binding.Type;
+import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
+import dagger.producers.Producer;
+import dagger.producers.ProductionComponent;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import javax.inject.Inject;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.common.base.Predicates.in;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Sets.union;
+import static dagger.internal.codegen.BindingKey.Kind.CONTRIBUTION;
+import static dagger.internal.codegen.ComponentDescriptor.isComponentContributionMethod;
+import static dagger.internal.codegen.ComponentDescriptor.isComponentProductionMethod;
+import static dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor.isOfKind;
+import static dagger.internal.codegen.ComponentDescriptor.ComponentMethodKind.SUBCOMPONENT_BUILDER;
+import static dagger.internal.codegen.ComponentDescriptor.Kind.PRODUCTION_COMPONENT;
+import static dagger.internal.codegen.ConfigurationAnnotations.getComponentDependencies;
+import static dagger.internal.codegen.MembersInjectionBinding.Strategy.INJECT_MEMBERS;
+import static dagger.internal.codegen.MembersInjectionBinding.Strategy.NO_OP;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * The canonical representation of a full-resolved graph.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class BindingGraph {
+  abstract ComponentDescriptor componentDescriptor();
+  abstract ImmutableMap<BindingKey, ResolvedBindings> resolvedBindings();
+  abstract ImmutableMap<ExecutableElement, BindingGraph> subgraphs();
+
+  /**
+   * Returns the set of modules that are owned by this graph regardless of whether or not any of
+   * their bindings are used in this graph. For graphs representing top-level {@link Component
+   * components}, this set will be the same as
+   * {@linkplain ComponentDescriptor#transitiveModules the component's transitive modules}. For
+   * {@linkplain Subcomponent subcomponents}, this set will be the transitive modules that are not
+   * owned by any of their ancestors.
+   */
+  abstract ImmutableSet<ModuleDescriptor> ownedModules();
+
+  ImmutableSet<TypeElement> ownedModuleTypes() {
+    return FluentIterable.from(ownedModules())
+        .transform(ModuleDescriptor.getModuleElement())
+        .toSet();
+  }
+
+  private static final TreeTraverser<BindingGraph> SUBGRAPH_TRAVERSER =
+      new TreeTraverser<BindingGraph>() {
+        @Override
+        public Iterable<BindingGraph> children(BindingGraph node) {
+          return node.subgraphs().values();
+        }
+      };
+
+  /**
+   * Returns the set of types necessary to implement the component, but are not part of the injected
+   * graph.  This includes modules, component dependencies and an {@link Executor} in the case of
+   * {@link ProductionComponent}.
+   */
+  ImmutableSet<TypeElement> componentRequirements() {
+    return SUBGRAPH_TRAVERSER
+        .preOrderTraversal(this)
+        .transformAndConcat(
+            new Function<BindingGraph, Iterable<ResolvedBindings>>() {
+              @Override
+              public Iterable<ResolvedBindings> apply(BindingGraph input) {
+                return input.resolvedBindings().values();
+              }
+            })
+        .transformAndConcat(
+            new Function<ResolvedBindings, Set<ContributionBinding>>() {
+              @Override
+              public Set<ContributionBinding> apply(ResolvedBindings input) {
+                return (input.bindingKey().kind().equals(CONTRIBUTION))
+                    ? input.contributionBindings()
+                    : ImmutableSet.<ContributionBinding>of();
+              }
+            })
+        .transformAndConcat(
+            new Function<ContributionBinding, Set<TypeElement>>() {
+              @Override
+              public Set<TypeElement> apply(ContributionBinding input) {
+                return input.bindingElement().getModifiers().contains(STATIC)
+                    ? ImmutableSet.<TypeElement>of()
+                    : input.contributedBy().asSet();
+              }
+            })
+        .filter(in(ownedModuleTypes()))
+        .append(componentDescriptor().dependencies())
+        .append(componentDescriptor().executorDependency().asSet())
+        .toSet();
+  }
+
+  ImmutableSet<TypeElement> availableDependencies() {
+    return new ImmutableSet.Builder<TypeElement>()
+        .addAll(componentDescriptor().transitiveModuleTypes())
+        .addAll(componentDescriptor().dependencies())
+        .addAll(componentDescriptor().executorDependency().asSet())
+        .build();
+  }
+
+  static final class Factory {
+    private final Elements elements;
+    private final InjectBindingRegistry injectBindingRegistry;
+    private final Key.Factory keyFactory;
+    private final ProvisionBinding.Factory provisionBindingFactory;
+    private final ProductionBinding.Factory productionBindingFactory;
+
+    Factory(Elements elements,
+        InjectBindingRegistry injectBindingRegistry,
+        Key.Factory keyFactory,
+        ProvisionBinding.Factory provisionBindingFactory,
+        ProductionBinding.Factory productionBindingFactory) {
+      this.elements = elements;
+      this.injectBindingRegistry = injectBindingRegistry;
+      this.keyFactory = keyFactory;
+      this.provisionBindingFactory = provisionBindingFactory;
+      this.productionBindingFactory = productionBindingFactory;
+    }
+
+    BindingGraph create(ComponentDescriptor componentDescriptor) {
+      return create(Optional.<Resolver>absent(), componentDescriptor);
+    }
+
+    private BindingGraph create(
+        Optional<Resolver> parentResolver, ComponentDescriptor componentDescriptor) {
+      ImmutableSet.Builder<ContributionBinding> explicitBindingsBuilder = ImmutableSet.builder();
+
+      // binding for the component itself
+      TypeElement componentDefinitionType = componentDescriptor.componentDefinitionType();
+      explicitBindingsBuilder.add(provisionBindingFactory.forComponent(componentDefinitionType));
+
+      // Collect Component dependencies.
+      Optional<AnnotationMirror> componentMirror =
+          getAnnotationMirror(componentDefinitionType, Component.class)
+              .or(getAnnotationMirror(componentDefinitionType, ProductionComponent.class));
+      ImmutableSet<TypeElement> componentDependencyTypes = componentMirror.isPresent()
+          ? MoreTypes.asTypeElements(getComponentDependencies(componentMirror.get()))
+          : ImmutableSet.<TypeElement>of();
+      for (TypeElement componentDependency : componentDependencyTypes) {
+        explicitBindingsBuilder.add(provisionBindingFactory.forComponent(componentDependency));
+        List<ExecutableElement> dependencyMethods =
+            ElementFilter.methodsIn(elements.getAllMembers(componentDependency));
+        for (ExecutableElement method : dependencyMethods) {
+          // MembersInjection methods aren't "provided" explicitly, so ignore them.
+          if (isComponentContributionMethod(elements, method)) {
+            explicitBindingsBuilder.add(
+                componentDescriptor.kind().equals(PRODUCTION_COMPONENT)
+                        && isComponentProductionMethod(elements, method)
+                    ? productionBindingFactory.forComponentMethod(method)
+                    : provisionBindingFactory.forComponentMethod(method));
+          }
+        }
+      }
+
+      // Bindings for subcomponent builders.
+      for (ComponentMethodDescriptor subcomponentMethodDescriptor :
+          Iterables.filter(
+              componentDescriptor.subcomponents().keySet(), isOfKind(SUBCOMPONENT_BUILDER))) {
+        explicitBindingsBuilder.add(
+            provisionBindingFactory.forSubcomponentBuilderMethod(
+                subcomponentMethodDescriptor.methodElement(),
+                componentDescriptor.componentDefinitionType()));
+      }
+
+      // Collect transitive module bindings.
+      for (ModuleDescriptor moduleDescriptor : componentDescriptor.transitiveModules()) {
+        for (ContributionBinding binding : moduleDescriptor.bindings()) {
+          explicitBindingsBuilder.add(binding);
+        }
+      }
+
+      Resolver requestResolver =
+          new Resolver(
+              parentResolver,
+              componentDescriptor,
+              explicitBindingsByKey(explicitBindingsBuilder.build()));
+      for (ComponentMethodDescriptor componentMethod : componentDescriptor.componentMethods()) {
+        Optional<DependencyRequest> componentMethodRequest = componentMethod.dependencyRequest();
+        if (componentMethodRequest.isPresent()) {
+          requestResolver.resolve(componentMethodRequest.get());
+        }
+      }
+
+      ImmutableMap.Builder<ExecutableElement, BindingGraph> subgraphsBuilder =
+          ImmutableMap.builder();
+      for (Entry<ComponentMethodDescriptor, ComponentDescriptor> subcomponentEntry :
+          componentDescriptor.subcomponents().entrySet()) {
+        subgraphsBuilder.put(
+            subcomponentEntry.getKey().methodElement(),
+            create(Optional.of(requestResolver), subcomponentEntry.getValue()));
+      }
+
+      for (ResolvedBindings resolvedBindings : requestResolver.getResolvedBindings().values()) {
+        verify(
+            resolvedBindings.owningComponent().equals(componentDescriptor),
+            "%s is not owned by %s",
+            resolvedBindings,
+            componentDescriptor);
+      }
+
+      return new AutoValue_BindingGraph(
+          componentDescriptor,
+          requestResolver.getResolvedBindings(),
+          subgraphsBuilder.build(),
+          requestResolver.getOwnedModules());
+    }
+
+    private <B extends ContributionBinding> ImmutableSetMultimap<Key, B> explicitBindingsByKey(
+        Iterable<? extends B> bindings) {
+      // Multimaps.index() doesn't do ImmutableSetMultimaps.
+      ImmutableSetMultimap.Builder<Key, B> builder = ImmutableSetMultimap.builder();
+      for (B binding : bindings) {
+        builder.put(binding.key(), binding);
+      }
+      return builder.build();
+    }
+
+    private final class Resolver {
+      final Optional<Resolver> parentResolver;
+      final ComponentDescriptor componentDescriptor;
+      final ImmutableSetMultimap<Key, ContributionBinding> explicitBindings;
+      final ImmutableSet<ContributionBinding> explicitBindingsSet;
+      final Map<BindingKey, ResolvedBindings> resolvedBindings;
+      final Deque<BindingKey> cycleStack = new ArrayDeque<>();
+      final Cache<BindingKey, Boolean> dependsOnLocalMultibindingsCache =
+          CacheBuilder.newBuilder().<BindingKey, Boolean>build();
+
+      Resolver(
+          Optional<Resolver> parentResolver,
+          ComponentDescriptor componentDescriptor,
+          ImmutableSetMultimap<Key, ContributionBinding> explicitBindings) {
+        assert parentResolver != null;
+        this.parentResolver = parentResolver;
+        assert componentDescriptor != null;
+        this.componentDescriptor = componentDescriptor;
+        assert explicitBindings != null;
+        this.explicitBindings = explicitBindings;
+        this.explicitBindingsSet = ImmutableSet.copyOf(explicitBindings.values());
+        this.resolvedBindings = Maps.newLinkedHashMap();
+      }
+
+      /**
+       * Looks up the bindings associated with a given dependency request and returns them.
+       *
+       * <p>Requests for {@code Map<K, V>} for which there are only bindings for
+       * {@code Map<K, Provider<V>>} will resolve to a single implicit binding for the latter map
+       * (and similarly for {@link Producer}s).
+       *
+       * <p>If there are no explicit bindings for a contribution, looks for implicit
+       * {@link Inject @Inject}-annotated constructor types.
+       */
+      ResolvedBindings lookUpBindings(DependencyRequest request) {
+        BindingKey bindingKey = request.bindingKey();
+        switch (bindingKey.kind()) {
+          case CONTRIBUTION:
+            // First, check for explicit keys (those from modules and components)
+            ImmutableSet<ContributionBinding> explicitBindingsForKey =
+                getExplicitBindings(bindingKey.key());
+
+            // If the key is Map<K, V>, get its implicit binding keys, which are either
+            // Map<K, Provider<V>> or Map<K, Producer<V>>, and grab their explicit bindings.
+            Optional<Key> mapProviderKey = keyFactory.implicitMapProviderKeyFrom(bindingKey.key());
+            ImmutableSet.Builder<ContributionBinding> explicitMapBindingsBuilder =
+                ImmutableSet.builder();
+            if (mapProviderKey.isPresent()) {
+              explicitMapBindingsBuilder.addAll(getExplicitBindings(mapProviderKey.get()));
+            }
+
+            Optional<Key> mapProducerKey = keyFactory.implicitMapProducerKeyFrom(bindingKey.key());
+            if (mapProducerKey.isPresent()) {
+              explicitMapBindingsBuilder.addAll(getExplicitBindings(mapProducerKey.get()));
+            }
+            ImmutableSet<ContributionBinding> explicitMapBindings =
+                explicitMapBindingsBuilder.build();
+
+            // If the key is Set<Produced<T>>, then we look up bindings by the alternate key Set<T>.
+            Optional<Key> setKeyFromProduced =
+                keyFactory.implicitSetKeyFromProduced(bindingKey.key());
+            ImmutableSet<ContributionBinding> explicitSetBindings =
+                setKeyFromProduced.isPresent()
+                    ? getExplicitBindings(setKeyFromProduced.get())
+                    : ImmutableSet.<ContributionBinding>of();
+
+            if (!explicitBindingsForKey.isEmpty() || !explicitSetBindings.isEmpty()) {
+              /* If there are any explicit bindings for this key, then combine those with any
+               * conflicting Map<K, Provider<V>> bindings and let the validator fail. */
+              ImmutableSetMultimap.Builder<ComponentDescriptor, ContributionBinding> bindings =
+                  ImmutableSetMultimap.builder();
+              for (ContributionBinding binding :
+                  union(explicitBindingsForKey, union(explicitSetBindings, explicitMapBindings))) {
+                bindings.put(getOwningComponent(request, binding), binding);
+              }
+              return ResolvedBindings.forContributionBindings(
+                  bindingKey, componentDescriptor, bindings.build());
+            } else if (any(explicitMapBindings, Binding.Type.PRODUCTION)) {
+              /* If this binding is for Map<K, V> and there are no explicit Map<K, V> bindings but
+               * some explicit Map<K, Producer<V>> bindings, then this binding must have only the
+               * implicit dependency on Map<K, Producer<V>>. */
+              return ResolvedBindings.forContributionBindings(
+                  bindingKey,
+                  componentDescriptor,
+                  productionBindingFactory.implicitMapOfProducerBinding(request));
+            } else if (any(explicitMapBindings, Binding.Type.PROVISION)) {
+              /* If this binding is for Map<K, V> and there are no explicit Map<K, V> bindings but
+               * some explicit Map<K, Provider<V>> bindings, then this binding must have only the
+               * implicit dependency on Map<K, Provider<V>>. */
+              return ResolvedBindings.forContributionBindings(
+                  bindingKey,
+                  componentDescriptor,
+                  provisionBindingFactory.implicitMapOfProviderBinding(request));
+            } else {
+              /* If there are no explicit bindings at all, look for an implicit @Inject-constructed
+               * binding. */
+              Optional<ProvisionBinding> provisionBinding =
+                  injectBindingRegistry.getOrFindProvisionBinding(bindingKey.key());
+              ComponentDescriptor owningComponent =
+                  provisionBinding.isPresent()
+                          && isResolvedInParent(request, provisionBinding.get())
+                          && !shouldOwnParentBinding(request, provisionBinding.get())
+                      ? getOwningResolver(provisionBinding.get()).get().componentDescriptor
+                      : componentDescriptor;
+              return ResolvedBindings.forContributionBindings(
+                  bindingKey,
+                  componentDescriptor,
+                  ImmutableSetMultimap.<ComponentDescriptor, ContributionBinding>builder()
+                      .putAll(owningComponent, provisionBinding.asSet())
+                      .build());
+            }
+
+          case MEMBERS_INJECTION:
+            // no explicit deps for members injection, so just look it up
+            return ResolvedBindings.forMembersInjectionBinding(
+                bindingKey, componentDescriptor, rollUpMembersInjectionBindings(bindingKey.key()));
+          default:
+            throw new AssertionError();
+        }
+      }
+
+      /**
+       * If {@code binding} should be owned by a parent component, resolves the binding in that
+       * component's resolver and returns that component. Otherwise returns the component for this
+       * resolver.
+       */
+      private ComponentDescriptor getOwningComponent(
+          DependencyRequest request, ContributionBinding binding) {
+        return isResolvedInParent(request, binding) && !shouldOwnParentBinding(request, binding)
+            ? getOwningResolver(binding).get().componentDescriptor
+            : componentDescriptor;
+      }
+
+      /**
+       * Returns {@code true} if {@code binding} is owned by a parent resolver. If so, calls
+       * {@link #resolve(DependencyRequest) resolve(request)} on that resolver.
+       */
+      private boolean isResolvedInParent(DependencyRequest request, ContributionBinding binding) {
+        Optional<Resolver> owningResolver = getOwningResolver(binding);
+        if (owningResolver.isPresent() && !owningResolver.get().equals(this)) {
+          owningResolver.get().resolve(request);
+          return true;
+        } else {
+          return false;
+        }
+      }
+
+      /**
+       * Returns {@code true} if {@code binding}, which was previously resolved by a parent
+       * resolver, should be moved into this resolver's bindings for {@code request} because it is
+       * unscoped and {@linkplain #dependsOnLocalMultibindings(ResolvedBindings) depends on local
+       * multibindings}, or {@code false} if it can satisfy {@code request} as an inherited binding.
+       */
+      private boolean shouldOwnParentBinding(
+          DependencyRequest request, ContributionBinding binding) {
+        return !binding.scope().isPresent()
+            && dependsOnLocalMultibindings(
+                getPreviouslyResolvedBindings(request.bindingKey()).get());
+      }
+
+      private MembersInjectionBinding rollUpMembersInjectionBindings(Key key) {
+        MembersInjectionBinding membersInjectionBinding =
+            injectBindingRegistry.getOrFindMembersInjectionBinding(key);
+
+        if (membersInjectionBinding.parentInjectorRequest().isPresent()
+            && membersInjectionBinding.injectionStrategy().equals(INJECT_MEMBERS)) {
+          MembersInjectionBinding parentBinding =
+              rollUpMembersInjectionBindings(
+                  membersInjectionBinding.parentInjectorRequest().get().key());
+          if (parentBinding.injectionStrategy().equals(NO_OP)) {
+            return membersInjectionBinding.withoutParentInjectorRequest();
+          }
+        }
+
+        return membersInjectionBinding;
+      }
+
+      private Optional<Resolver> getOwningResolver(ContributionBinding provisionBinding) {
+        for (Resolver requestResolver : getResolverLineage().reverse()) {
+          if (requestResolver.explicitBindingsSet.contains(provisionBinding)) {
+            return Optional.of(requestResolver);
+          }
+        }
+
+        // look for scope separately.  we do this for the case where @Singleton can appear twice
+        // in the † compatibility mode
+        Scope bindingScope = provisionBinding.scope();
+        if (bindingScope.isPresent()) {
+          for (Resolver requestResolver : getResolverLineage().reverse()) {
+            if (bindingScope.equals(requestResolver.componentDescriptor.scope())) {
+              return Optional.of(requestResolver);
+            }
+          }
+        }
+        return Optional.absent();
+      }
+
+      /** Returns the resolver lineage from parent to child. */
+      private ImmutableList<Resolver> getResolverLineage() {
+        List<Resolver> resolverList = Lists.newArrayList();
+        for (Optional<Resolver> currentResolver = Optional.of(this);
+            currentResolver.isPresent();
+            currentResolver = currentResolver.get().parentResolver) {
+          resolverList.add(currentResolver.get());
+        }
+        return ImmutableList.copyOf(Lists.reverse(resolverList));
+      }
+
+      private ImmutableSet<ContributionBinding> getExplicitBindings(Key requestKey) {
+        ImmutableSet.Builder<ContributionBinding> explicitBindingsForKey = ImmutableSet.builder();
+        for (Resolver resolver : getResolverLineage()) {
+          explicitBindingsForKey.addAll(resolver.explicitBindings.get(requestKey));
+        }
+        return explicitBindingsForKey.build();
+      }
+
+      private Optional<ResolvedBindings> getPreviouslyResolvedBindings(
+          final BindingKey bindingKey) {
+        Optional<ResolvedBindings> result = Optional.fromNullable(resolvedBindings.get(bindingKey));
+        if (result.isPresent()) {
+          return result;
+        } else if (parentResolver.isPresent()) {
+          return parentResolver.get().getPreviouslyResolvedBindings(bindingKey);
+        } else {
+          return Optional.absent();
+        }
+      }
+
+      void resolve(DependencyRequest request) {
+        BindingKey bindingKey = request.bindingKey();
+
+        // If we find a cycle, stop resolving. The original request will add it with all of the
+        // other resolved deps.
+        if (cycleStack.contains(bindingKey)) {
+          return;
+        }
+
+        // If the binding was previously resolved in this (sub)component, don't resolve it again.
+        if (resolvedBindings.containsKey(bindingKey)) {
+          return;
+        }
+
+        // If the binding was previously resolved in a supercomponent, then test to see if it
+        // depends on multibindings with contributions from this subcomponent. If it does, then we
+        // have to resolve it in this subcomponent so that it sees the local contributions. If it
+        // does not, then we can stop resolving it in this subcomponent and rely on the
+        // supercomponent resolution.
+        Optional<ResolvedBindings> bindingsPreviouslyResolvedInParent =
+            getPreviouslyResolvedBindings(bindingKey);
+        if (bindingsPreviouslyResolvedInParent.isPresent()
+            && !dependsOnLocalMultibindings(bindingsPreviouslyResolvedInParent.get())) {
+          return;
+        }
+
+        cycleStack.push(bindingKey);
+        try {
+          ResolvedBindings bindings = lookUpBindings(request);
+          for (Binding binding : bindings.ownedBindings()) {
+            for (DependencyRequest dependency : binding.implicitDependencies()) {
+              resolve(dependency);
+            }
+          }
+          resolvedBindings.put(bindingKey, bindings);
+        } finally {
+          cycleStack.pop();
+        }
+      }
+
+      /**
+       * Returns {@code true} if {@code previouslyResolvedBindings} is multibindings with
+       * contributions declared within this (sub)component's modules, or if any of its unscoped
+       * provision-dependencies depend on such local multibindings.
+       *
+       * <p>We don't care about scoped dependencies or production bindings because they will never
+       * depend on multibindings with contributions from subcomponents.
+       */
+      private boolean dependsOnLocalMultibindings(ResolvedBindings previouslyResolvedBindings) {
+        return dependsOnLocalMultibindings(previouslyResolvedBindings, new HashSet<BindingKey>());
+      }
+
+      private boolean dependsOnLocalMultibindings(
+          final ResolvedBindings previouslyResolvedBindings, final Set<BindingKey> cycleChecker) {
+        // Don't recur infinitely if there are valid cycles in the dependency graph.
+        if (!cycleChecker.add(previouslyResolvedBindings.bindingKey())) {
+          return false;
+        }
+        try {
+          return dependsOnLocalMultibindingsCache.get(
+              previouslyResolvedBindings.bindingKey(),
+              new Callable<Boolean>() {
+                @Override
+                public Boolean call() {
+                  if (previouslyResolvedBindings.isMultibindings()
+                      && hasLocalContributions(previouslyResolvedBindings)) {
+                    return true;
+                  }
+
+                  for (Binding binding : previouslyResolvedBindings.bindings()) {
+                    if (!binding.scope().isPresent()
+                        && !binding.bindingType().equals(Type.PRODUCTION)) {
+                      for (DependencyRequest dependency : binding.implicitDependencies()) {
+                        if (dependsOnLocalMultibindings(
+                            getPreviouslyResolvedBindings(dependency.bindingKey()).get(),
+                            cycleChecker)) {
+                          return true;
+                        }
+                      }
+                    }
+                  }
+                  return false;
+                }
+              });
+        } catch (ExecutionException e) {
+          throw new AssertionError(e);
+        }
+      }
+
+      private boolean hasLocalContributions(ResolvedBindings resolvedBindings) {
+        return !explicitBindings.get(resolvedBindings.bindingKey().key()).isEmpty();
+      }
+
+      ImmutableMap<BindingKey, ResolvedBindings> getResolvedBindings() {
+        ImmutableMap.Builder<BindingKey, ResolvedBindings> resolvedBindingsBuilder =
+            ImmutableMap.builder();
+        resolvedBindingsBuilder.putAll(resolvedBindings);
+        if (parentResolver.isPresent()) {
+          Collection<ResolvedBindings> bindingsResolvedInParent =
+              Maps.difference(parentResolver.get().getResolvedBindings(), resolvedBindings)
+                  .entriesOnlyOnLeft()
+                  .values();
+          for (ResolvedBindings resolvedInParent : bindingsResolvedInParent) {
+            resolvedBindingsBuilder.put(
+                resolvedInParent.bindingKey(),
+                resolvedInParent.asInheritedIn(componentDescriptor));
+          }
+        }
+        return resolvedBindingsBuilder.build();
+      }
+
+      ImmutableSet<ModuleDescriptor> getInheritedModules() {
+        return parentResolver.isPresent()
+            ? Sets.union(
+                    parentResolver.get().getInheritedModules(),
+                    parentResolver.get().componentDescriptor.transitiveModules())
+                .immutableCopy()
+            : ImmutableSet.<ModuleDescriptor>of();
+      }
+
+      ImmutableSet<ModuleDescriptor> getOwnedModules() {
+        return Sets.difference(componentDescriptor.transitiveModules(), getInheritedModules())
+            .immutableCopy();
+      }
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingGraphValidator.java b/compiler/src/main/java/dagger/internal/codegen/BindingGraphValidator.java
new file mode 100644
index 0000000..f8010c3
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/BindingGraphValidator.java
@@ -0,0 +1,1160 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import dagger.Component;
+import dagger.Lazy;
+import dagger.MapKey;
+import dagger.internal.codegen.ComponentDescriptor.BuilderSpec;
+import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
+import dagger.internal.codegen.ContributionBinding.ContributionType;
+import dagger.internal.codegen.writer.TypeNames;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.auto.common.MoreTypes.asDeclared;
+import static com.google.auto.common.MoreTypes.asExecutable;
+import static com.google.auto.common.MoreTypes.asTypeElements;
+import static com.google.common.base.Predicates.equalTo;
+import static com.google.common.base.Predicates.in;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.collect.Iterables.all;
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.indexOf;
+import static com.google.common.collect.Iterables.skip;
+import static com.google.common.collect.Maps.filterKeys;
+import static dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor.isOfKind;
+import static dagger.internal.codegen.ComponentDescriptor.ComponentMethodKind.SUBCOMPONENT;
+import static dagger.internal.codegen.ConfigurationAnnotations.getComponentDependencies;
+import static dagger.internal.codegen.ContributionBinding.indexMapBindingsByAnnotationType;
+import static dagger.internal.codegen.ContributionBinding.indexMapBindingsByMapKey;
+import static dagger.internal.codegen.ErrorMessages.DUPLICATE_SIZE_LIMIT;
+import static dagger.internal.codegen.ErrorMessages.INDENT;
+import static dagger.internal.codegen.ErrorMessages.MEMBERS_INJECTION_WITH_UNBOUNDED_TYPE;
+import static dagger.internal.codegen.ErrorMessages.REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_FORMAT;
+import static dagger.internal.codegen.ErrorMessages.REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_OR_PRODUCER_FORMAT;
+import static dagger.internal.codegen.ErrorMessages.REQUIRES_PROVIDER_FORMAT;
+import static dagger.internal.codegen.ErrorMessages.REQUIRES_PROVIDER_OR_PRODUCER_FORMAT;
+import static dagger.internal.codegen.ErrorMessages.duplicateMapKeysError;
+import static dagger.internal.codegen.ErrorMessages.inconsistentMapKeyAnnotationsError;
+import static dagger.internal.codegen.ErrorMessages.nullableToNonNullable;
+import static dagger.internal.codegen.ErrorMessages.stripCommonTypePrefixes;
+import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
+import static dagger.internal.codegen.Util.getKeyTypeOfMap;
+import static dagger.internal.codegen.Util.getProvidedValueTypeOfMap;
+import static dagger.internal.codegen.Util.getValueTypeOfMap;
+import static dagger.internal.codegen.Util.isMapWithNonProvidedValues;
+import static dagger.internal.codegen.Util.isMapWithProvidedValues;
+import static javax.tools.Diagnostic.Kind.ERROR;
+import static javax.tools.Diagnostic.Kind.WARNING;
+
+public class BindingGraphValidator {
+
+  private final Types types;
+  private final InjectBindingRegistry injectBindingRegistry;
+  private final ValidationType scopeCycleValidationType;
+  private final Diagnostic.Kind nullableValidationType;
+  private final ContributionBindingFormatter contributionBindingFormatter;
+  private final MethodSignatureFormatter methodSignatureFormatter;
+  private final DependencyRequestFormatter dependencyRequestFormatter;
+  private final KeyFormatter keyFormatter;
+
+  BindingGraphValidator(
+      Types types,
+      InjectBindingRegistry injectBindingRegistry,
+      ValidationType scopeCycleValidationType,
+      Diagnostic.Kind nullableValidationType,
+      ContributionBindingFormatter contributionBindingFormatter,
+      MethodSignatureFormatter methodSignatureFormatter,
+      DependencyRequestFormatter dependencyRequestFormatter,
+      KeyFormatter keyFormatter) {
+    this.types = types;
+    this.injectBindingRegistry = injectBindingRegistry;
+    this.scopeCycleValidationType = scopeCycleValidationType;
+    this.nullableValidationType = nullableValidationType;
+    this.contributionBindingFormatter = contributionBindingFormatter;
+    this.methodSignatureFormatter = methodSignatureFormatter;
+    this.dependencyRequestFormatter = dependencyRequestFormatter;
+    this.keyFormatter = keyFormatter;
+  }
+
+  private class Validation {
+    final BindingGraph topLevelGraph;
+    final BindingGraph subject;
+    final ValidationReport.Builder<TypeElement> reportBuilder;
+
+    Validation(BindingGraph topLevelGraph, BindingGraph subject) {
+      this.topLevelGraph = topLevelGraph;
+      this.subject = subject;
+      this.reportBuilder =
+          ValidationReport.about(subject.componentDescriptor().componentDefinitionType());
+    }
+
+    Validation(BindingGraph topLevelGraph) {
+      this(topLevelGraph, topLevelGraph);
+    }
+
+    ValidationReport<TypeElement> buildReport() {
+      return reportBuilder.build();
+    }
+
+    void validateSubgraph() {
+      validateComponentScope();
+      validateDependencyScopes();
+      validateComponentHierarchy();
+      validateBuilders();
+
+      for (ComponentMethodDescriptor componentMethod :
+           subject.componentDescriptor().componentMethods()) {
+        Optional<DependencyRequest> entryPoint = componentMethod.dependencyRequest();
+        if (entryPoint.isPresent()) {
+          traverseRequest(
+              entryPoint.get(),
+              new ArrayDeque<ResolvedRequest>(),
+              new LinkedHashSet<BindingKey>(),
+              subject,
+              new HashSet<DependencyRequest>());
+        }
+      }
+      
+      for (Map.Entry<ComponentMethodDescriptor, ComponentDescriptor> entry :
+          filterKeys(subject.componentDescriptor().subcomponents(), isOfKind(SUBCOMPONENT))
+              .entrySet()) {
+        validateSubcomponentFactoryMethod(
+            entry.getKey().methodElement(), entry.getValue().componentDefinitionType());
+      }
+
+      for (BindingGraph subgraph : subject.subgraphs().values()) {
+        Validation subgraphValidation =
+            new Validation(topLevelGraph, subgraph);
+        subgraphValidation.validateSubgraph();
+        reportBuilder.addSubreport(subgraphValidation.buildReport());
+      }
+    }
+
+    private void validateSubcomponentFactoryMethod(
+        ExecutableElement factoryMethod, TypeElement subcomponentType) {
+      BindingGraph subgraph = subject.subgraphs().get(factoryMethod);
+      FluentIterable<TypeElement> missingModules =
+          FluentIterable.from(subgraph.componentRequirements())
+              .filter(not(in(subgraphFactoryMethodParameters(factoryMethod))))
+              .filter(
+                  new Predicate<TypeElement>() {
+                    @Override
+                    public boolean apply(TypeElement moduleType) {
+                      return !componentCanMakeNewInstances(moduleType);
+                    }
+                  });
+      if (!missingModules.isEmpty()) {
+        reportBuilder.addError(
+            String.format(
+                "%s requires modules which have no visible default constructors. "
+                    + "Add the following modules as parameters to this method: %s",
+                subcomponentType.getQualifiedName(),
+                Joiner.on(", ").join(missingModules.toSet())),
+            factoryMethod);
+      }
+    }
+
+    private ImmutableSet<TypeElement> subgraphFactoryMethodParameters(
+        ExecutableElement factoryMethod) {
+      DeclaredType componentType =
+          asDeclared(subject.componentDescriptor().componentDefinitionType().asType());
+      ExecutableType factoryMethodType =
+          asExecutable(types.asMemberOf(componentType, factoryMethod));
+      return asTypeElements(factoryMethodType.getParameterTypes());
+    }
+
+    /**
+     * Traverse the resolved dependency requests, validating resolved bindings, and reporting any
+     * cycles found.
+     *
+     * @param request the current dependency request
+     * @param bindingPath the dependency request path from the parent of {@code request} at the head
+     *     up to the root dependency request from the component method at the tail
+     * @param keysInPath the binding keys corresponding to the dependency requests in
+     *     {@code bindingPath}, but in reverse order: the first element is the binding key from the
+     *     component method
+     * @param resolvedRequests the requests that have already been resolved, so we can avoid
+     *     traversing that part of the graph again
+     */
+    // TODO(dpb): It might be simpler to invert bindingPath's order.
+    private void traverseRequest(
+        DependencyRequest request,
+        Deque<ResolvedRequest> bindingPath,
+        LinkedHashSet<BindingKey> keysInPath,
+        BindingGraph graph,
+        Set<DependencyRequest> resolvedRequests) {
+      verify(bindingPath.size() == keysInPath.size(),
+          "mismatched path vs keys -- (%s vs %s)", bindingPath, keysInPath);
+      BindingKey requestKey = request.bindingKey();
+      if (keysInPath.contains(requestKey)) {
+        reportCycle(
+            // Invert bindingPath to match keysInPath's order
+            ImmutableList.copyOf(bindingPath).reverse(),
+            request,
+            indexOf(keysInPath, equalTo(requestKey)));
+        return;
+      }
+
+      // If request has already been resolved, avoid re-traversing the binding path.
+      if (resolvedRequests.add(request)) {
+        ResolvedRequest resolvedRequest = ResolvedRequest.create(request, graph);
+        bindingPath.push(resolvedRequest);
+        keysInPath.add(requestKey);
+        validateResolvedBinding(bindingPath, resolvedRequest.binding());
+
+        for (Binding binding : resolvedRequest.binding().bindings()) {
+          for (DependencyRequest nextRequest : binding.implicitDependencies()) {
+            traverseRequest(nextRequest, bindingPath, keysInPath, graph, resolvedRequests);
+          }
+        }
+        bindingPath.poll();
+        keysInPath.remove(requestKey);
+      }
+    }
+
+    /**
+     * Validates that the set of bindings resolved is consistent with the type of the binding, and
+     * returns true if the bindings are valid.
+     */
+    private boolean validateResolvedBinding(
+        Deque<ResolvedRequest> path, ResolvedBindings resolvedBinding) {
+      if (resolvedBinding.bindings().isEmpty()) {
+        reportMissingBinding(path);
+        return false;
+      }
+
+      switch (resolvedBinding.bindingKey().kind()) {
+        case CONTRIBUTION:
+          ImmutableSet<ContributionBinding> contributionBindings =
+              resolvedBinding.contributionBindings();
+          if (any(contributionBindings, Binding.Type.MEMBERS_INJECTION)) {
+            throw new IllegalArgumentException(
+                "contribution binding keys should never have members injection bindings");
+          }
+          if (!validateNullability(path.peek().request(), contributionBindings)) {
+            return false;
+          }
+          if (any(contributionBindings, Binding.Type.PRODUCTION)
+              && doesPathRequireProvisionOnly(path)) {
+            reportProviderMayNotDependOnProducer(path);
+            return false;
+          }
+          if (contributionBindings.size() <= 1) {
+            return true;
+          }
+          ImmutableListMultimap<ContributionType, ContributionBinding> contributionsByType =
+              ContributionBinding.contributionTypesFor(contributionBindings);
+          if (contributionsByType.keySet().size() > 1) {
+            reportMultipleBindingTypes(path);
+            return false;
+          }
+          switch (getOnlyElement(contributionsByType.keySet())) {
+            case UNIQUE:
+              reportDuplicateBindings(path);
+              return false;
+            case MAP:
+              boolean duplicateMapKeys = hasDuplicateMapKeys(path, contributionBindings);
+              boolean inconsistentMapKeyAnnotationTypes =
+                  hasInconsistentMapKeyAnnotationTypes(path, contributionBindings);
+              return !duplicateMapKeys && !inconsistentMapKeyAnnotationTypes;
+            case SET:
+              break;
+            default:
+              throw new AssertionError();
+          }
+          break;
+        case MEMBERS_INJECTION:
+          if (!all(resolvedBinding.bindings(), Binding.Type.MEMBERS_INJECTION)) {
+            throw new IllegalArgumentException(
+                "members injection binding keys should never have contribution bindings");
+          }
+          if (resolvedBinding.bindings().size() > 1) {
+            reportDuplicateBindings(path);
+            return false;
+          }
+          return validateMembersInjectionBinding(getOnlyElement(resolvedBinding.bindings()), path);
+        default:
+          throw new AssertionError();
+      }
+      return true;
+    }
+
+    /** Ensures that if the request isn't nullable, then each contribution is also not nullable. */
+    private boolean validateNullability(
+        DependencyRequest request, Set<ContributionBinding> bindings) {
+      if (request.isNullable()) {
+        return true;
+      }
+
+      // Note: the method signature will include the @Nullable in it!
+      /* TODO(sameb): Sometimes javac doesn't include the Element in its output.
+       * (Maybe this happens if the code was already compiled before this point?)
+       * ... we manually print out the request in that case, otherwise the error
+       * message is kind of useless. */
+      String typeName = TypeNames.forTypeMirror(request.key().type()).toString();
+
+      boolean valid = true;
+      for (ContributionBinding binding : bindings) {
+        if (binding.nullableType().isPresent()) {
+          reportBuilder.addItem(
+              nullableToNonNullable(typeName, contributionBindingFormatter.format(binding))
+                  + "\n at: "
+                  + dependencyRequestFormatter.format(request),
+              nullableValidationType,
+              request.requestElement());
+          valid = false;
+        }
+      }
+      return valid;
+    }
+
+    /**
+     * Returns {@code true} (and reports errors) if {@code mapBindings} has more than one binding
+     * for the same map key.
+     */
+    private boolean hasDuplicateMapKeys(
+        Deque<ResolvedRequest> path, Set<ContributionBinding> mapBindings) {
+      boolean hasDuplicateMapKeys = false;
+      for (Collection<ContributionBinding> mapBindingsForMapKey :
+          indexMapBindingsByMapKey(mapBindings).asMap().values()) {
+        if (mapBindingsForMapKey.size() > 1) {
+          hasDuplicateMapKeys = true;
+          reportDuplicateMapKeys(path, mapBindingsForMapKey);
+        }
+      }
+      return hasDuplicateMapKeys;
+    }
+
+    /**
+     * Returns {@code true} (and reports errors) if {@code mapBindings} uses more than one
+     * {@link MapKey} annotation type.
+     */
+    private boolean hasInconsistentMapKeyAnnotationTypes(
+        Deque<ResolvedRequest> path, Set<ContributionBinding> contributionBindings) {
+      ImmutableSetMultimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding>
+          mapBindingsByAnnotationType = indexMapBindingsByAnnotationType(contributionBindings);
+      if (mapBindingsByAnnotationType.keySet().size() > 1) {
+        reportInconsistentMapKeyAnnotations(path, mapBindingsByAnnotationType);
+        return true;
+      }
+      return false;
+    }
+
+    /**
+     * Validates a members injection binding, returning false (and reporting the error) if it wasn't
+     * valid.
+     */
+    private boolean validateMembersInjectionBinding(
+        Binding binding, final Deque<ResolvedRequest> path) {
+      return binding
+          .key()
+          .type()
+          .accept(
+              new SimpleTypeVisitor6<Boolean, Void>() {
+                @Override
+                protected Boolean defaultAction(TypeMirror e, Void p) {
+                  reportBuilder.addError(
+                      "Invalid members injection request.", path.peek().request().requestElement());
+                  return false;
+                }
+
+                @Override
+                public Boolean visitDeclared(DeclaredType type, Void ignored) {
+                  // If the key has type arguments, validate that each type argument is declared.
+                  // Otherwise the type argument may be a wildcard (or other type), and we can't
+                  // resolve that to actual types.  If the arg was an array, validate the type
+                  // of the array.
+                  for (TypeMirror arg : type.getTypeArguments()) {
+                    boolean declared;
+                    switch (arg.getKind()) {
+                      case ARRAY:
+                        declared =
+                            MoreTypes.asArray(arg)
+                                .getComponentType()
+                                .accept(
+                                    new SimpleTypeVisitor6<Boolean, Void>() {
+                                      @Override
+                                      protected Boolean defaultAction(TypeMirror e, Void p) {
+                                        return false;
+                                      }
+
+                                      @Override
+                                      public Boolean visitDeclared(DeclaredType t, Void p) {
+                                        for (TypeMirror arg : t.getTypeArguments()) {
+                                          if (!arg.accept(this, null)) {
+                                            return false;
+                                          }
+                                        }
+                                        return true;
+                                      }
+
+                                      @Override
+                                      public Boolean visitArray(ArrayType t, Void p) {
+                                        return t.getComponentType().accept(this, null);
+                                      }
+
+                                      @Override
+                                      public Boolean visitPrimitive(PrimitiveType t, Void p) {
+                                        return true;
+                                      }
+                                    },
+                                    null);
+                        break;
+                      case DECLARED:
+                        declared = true;
+                        break;
+                      default:
+                        declared = false;
+                    }
+                    if (!declared) {
+                      ImmutableList<String> printableDependencyPath =
+                          FluentIterable.from(path)
+                              .transform(REQUEST_FROM_RESOLVED_REQUEST)
+                              .transform(dependencyRequestFormatter)
+                              .filter(Predicates.not(Predicates.equalTo("")))
+                              .toList()
+                              .reverse();
+                      reportBuilder.addError(
+                          String.format(
+                              MEMBERS_INJECTION_WITH_UNBOUNDED_TYPE,
+                              arg.toString(),
+                              type.toString(),
+                              Joiner.on('\n').join(printableDependencyPath)),
+                          path.peek().request().requestElement());
+                      return false;
+                    }
+                  }
+
+                  TypeElement element = MoreElements.asType(type.asElement());
+                  // Also validate that the key is not the erasure of a generic type.
+                  // If it is, that means the user referred to Foo<T> as just 'Foo',
+                  // which we don't allow.  (This is a judgement call -- we *could*
+                  // allow it and instantiate the type bounds... but we don't.)
+                  if (!MoreTypes.asDeclared(element.asType()).getTypeArguments().isEmpty()
+                      && types.isSameType(types.erasure(element.asType()), type)) {
+                    ImmutableList<String> printableDependencyPath =
+                        FluentIterable.from(path)
+                            .transform(REQUEST_FROM_RESOLVED_REQUEST)
+                            .transform(dependencyRequestFormatter)
+                            .filter(Predicates.not(Predicates.equalTo("")))
+                            .toList()
+                            .reverse();
+                    reportBuilder.addError(
+                        String.format(
+                            ErrorMessages.MEMBERS_INJECTION_WITH_RAW_TYPE,
+                            type.toString(),
+                            Joiner.on('\n').join(printableDependencyPath)),
+                        path.peek().request().requestElement());
+                    return false;
+                  }
+
+                  return true; // valid
+                }
+              },
+              null);
+    }
+
+    /**
+     * Validates that component dependencies do not form a cycle.
+     */
+    private void validateComponentHierarchy() {
+      ComponentDescriptor descriptor = subject.componentDescriptor();
+      TypeElement componentType = descriptor.componentDefinitionType();
+      validateComponentHierarchy(componentType, componentType, new ArrayDeque<TypeElement>());
+    }
+
+    /**
+     * Recursive method to validate that component dependencies do not form a cycle.
+     */
+    private void validateComponentHierarchy(
+        TypeElement rootComponent,
+        TypeElement componentType,
+        Deque<TypeElement> componentStack) {
+
+      if (componentStack.contains(componentType)) {
+        // Current component has already appeared in the component chain.
+        StringBuilder message = new StringBuilder();
+        message.append(rootComponent.getQualifiedName());
+        message.append(" contains a cycle in its component dependencies:\n");
+        componentStack.push(componentType);
+        appendIndentedComponentsList(message, componentStack);
+        componentStack.pop();
+        reportBuilder.addItem(message.toString(),
+            scopeCycleValidationType.diagnosticKind().get(),
+            rootComponent, getAnnotationMirror(rootComponent, Component.class).get());
+      } else {
+        Optional<AnnotationMirror> componentAnnotation =
+            getAnnotationMirror(componentType, Component.class);
+        if (componentAnnotation.isPresent()) {
+          componentStack.push(componentType);
+
+          ImmutableSet<TypeElement> dependencies =
+              MoreTypes.asTypeElements(getComponentDependencies(componentAnnotation.get()));
+          for (TypeElement dependency : dependencies) {
+            validateComponentHierarchy(rootComponent, dependency, componentStack);
+          }
+
+          componentStack.pop();
+        }
+      }
+    }
+
+    /**
+     * Validates that among the dependencies are at most one scoped dependency,
+     * that there are no cycles within the scoping chain, and that singleton
+     * components have no scoped dependencies.
+     */
+    private void validateDependencyScopes() {
+      ComponentDescriptor descriptor = subject.componentDescriptor();
+      Scope scope = descriptor.scope();
+      ImmutableSet<TypeElement> scopedDependencies = scopedTypesIn(descriptor.dependencies());
+      if (scope.isPresent()) {
+        // Dagger 1.x scope compatibility requires this be suppress-able.
+        if (scopeCycleValidationType.diagnosticKind().isPresent()
+            && scope.isSingleton()) {
+          // Singleton is a special-case representing the longest lifetime, and therefore
+          // @Singleton components may not depend on scoped components
+          if (!scopedDependencies.isEmpty()) {
+            StringBuilder message = new StringBuilder(
+                "This @Singleton component cannot depend on scoped components:\n");
+            appendIndentedComponentsList(message, scopedDependencies);
+            reportBuilder.addItem(message.toString(),
+                scopeCycleValidationType.diagnosticKind().get(),
+                descriptor.componentDefinitionType(),
+                descriptor.componentAnnotation());
+          }
+        } else if (scopedDependencies.size() > 1) {
+          // Scoped components may depend on at most one scoped component.
+          StringBuilder message = new StringBuilder(scope.getReadableSource())
+              .append(' ')
+              .append(descriptor.componentDefinitionType().getQualifiedName())
+              .append(" depends on more than one scoped component:\n");
+          appendIndentedComponentsList(message, scopedDependencies);
+          reportBuilder.addError(
+              message.toString(),
+              descriptor.componentDefinitionType(),
+              descriptor.componentAnnotation());
+        } else {
+          // Dagger 1.x scope compatibility requires this be suppress-able.
+          if (!scopeCycleValidationType.equals(ValidationType.NONE)) {
+            validateScopeHierarchy(descriptor.componentDefinitionType(),
+                descriptor.componentDefinitionType(),
+                new ArrayDeque<Scope>(),
+                new ArrayDeque<TypeElement>());
+          }
+        }
+      } else {
+        // Scopeless components may not depend on scoped components.
+        if (!scopedDependencies.isEmpty()) {
+          StringBuilder message =
+              new StringBuilder(descriptor.componentDefinitionType().getQualifiedName())
+                  .append(" (unscoped) cannot depend on scoped components:\n");
+          appendIndentedComponentsList(message, scopedDependencies);
+          reportBuilder.addError(
+              message.toString(),
+              descriptor.componentDefinitionType(),
+              descriptor.componentAnnotation());
+        }
+      }
+    }
+
+    private void validateBuilders() {
+      ComponentDescriptor componentDesc = subject.componentDescriptor();
+      if (!componentDesc.builderSpec().isPresent()) {
+        // If no builder, nothing to validate.
+        return;
+      }
+
+      Set<TypeElement> availableDependencies = subject.availableDependencies();
+      Set<TypeElement> requiredDependencies =
+          Sets.filter(
+              availableDependencies,
+              new Predicate<TypeElement>() {
+                @Override
+                public boolean apply(TypeElement input) {
+                  return !Util.componentCanMakeNewInstances(input);
+                }
+              });
+      final BuilderSpec spec = componentDesc.builderSpec().get();
+      Map<TypeElement, ExecutableElement> allSetters = spec.methodMap();
+
+      ErrorMessages.ComponentBuilderMessages msgs =
+          ErrorMessages.builderMsgsFor(subject.componentDescriptor().kind());
+      Set<TypeElement> extraSetters = Sets.difference(allSetters.keySet(), availableDependencies);
+      if (!extraSetters.isEmpty()) {
+        Collection<ExecutableElement> excessMethods =
+            Maps.filterKeys(allSetters, Predicates.in(extraSetters)).values();
+        Iterable<String> formatted = FluentIterable.from(excessMethods).transform(
+            new Function<ExecutableElement, String>() {
+              @Override public String apply(ExecutableElement input) {
+                return methodSignatureFormatter.format(input,
+                    Optional.of(MoreTypes.asDeclared(spec.builderDefinitionType().asType())));
+              }});
+        reportBuilder.addError(
+            String.format(msgs.extraSetters(), formatted), spec.builderDefinitionType());
+      }
+
+      Set<TypeElement> missingSetters = Sets.difference(requiredDependencies, allSetters.keySet());
+      if (!missingSetters.isEmpty()) {
+        reportBuilder.addError(
+            String.format(msgs.missingSetters(), missingSetters), spec.builderDefinitionType());
+      }
+    }
+
+    /**
+     * Validates that scopes do not participate in a scoping cycle - that is to say, scoped
+     * components are in a hierarchical relationship terminating with Singleton.
+     *
+     * <p>As a side-effect, this means scoped components cannot have a dependency cycle between
+     * themselves, since a component's presence within its own dependency path implies a cyclical
+     * relationship between scopes. However, cycles in component dependencies are explicitly
+     * checked in {@link #validateComponentHierarchy()}.
+     */
+    private void validateScopeHierarchy(TypeElement rootComponent,
+        TypeElement componentType,
+        Deque<Scope> scopeStack,
+        Deque<TypeElement> scopedDependencyStack) {
+      Scope scope = Scope.scopeOf(componentType);
+      if (scope.isPresent()) {
+        if (scopeStack.contains(scope)) {
+          scopedDependencyStack.push(componentType);
+          // Current scope has already appeared in the component chain.
+          StringBuilder message = new StringBuilder();
+          message.append(rootComponent.getQualifiedName());
+          message.append(" depends on scoped components in a non-hierarchical scope ordering:\n");
+          appendIndentedComponentsList(message, scopedDependencyStack);
+          if (scopeCycleValidationType.diagnosticKind().isPresent()) {
+            reportBuilder.addItem(message.toString(),
+                scopeCycleValidationType.diagnosticKind().get(),
+                rootComponent, getAnnotationMirror(rootComponent, Component.class).get());
+          }
+          scopedDependencyStack.pop();
+        } else {
+          Optional<AnnotationMirror> componentAnnotation =
+              getAnnotationMirror(componentType, Component.class);
+          if (componentAnnotation.isPresent()) {
+            ImmutableSet<TypeElement> scopedDependencies = scopedTypesIn(
+                MoreTypes.asTypeElements(getComponentDependencies(componentAnnotation.get())));
+            if (scopedDependencies.size() == 1) {
+              // empty can be ignored (base-case), and > 1 is a different error reported separately.
+              scopeStack.push(scope);
+              scopedDependencyStack.push(componentType);
+              validateScopeHierarchy(rootComponent, getOnlyElement(scopedDependencies),
+                  scopeStack, scopedDependencyStack);
+              scopedDependencyStack.pop();
+              scopeStack.pop();
+            }
+          } // else: we skip component dependencies which are not components
+        }
+      }
+    }
+
+    /**
+     * Validates that the scope (if any) of this component are compatible with the scopes of the
+     * bindings available in this component
+     */
+    void validateComponentScope() {
+      ImmutableMap<BindingKey, ResolvedBindings> resolvedBindings = subject.resolvedBindings();
+      Scope componentScope = subject.componentDescriptor().scope();
+      ImmutableSet.Builder<String> incompatiblyScopedMethodsBuilder = ImmutableSet.builder();
+      for (ResolvedBindings bindings : resolvedBindings.values()) {
+        if (bindings.bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION)) {
+          for (ContributionBinding contributionBinding : bindings.ownedContributionBindings()) {
+            Scope bindingScope = contributionBinding.scope();
+            if (bindingScope.isPresent() && !bindingScope.equals(componentScope)) {
+              // Scoped components cannot reference bindings to @Provides methods or @Inject
+              // types decorated by a different scope annotation. Unscoped components cannot
+              // reference to scoped @Provides methods or @Inject types decorated by any
+              // scope annotation.
+              switch (contributionBinding.bindingKind()) {
+                case PROVISION:
+                  ExecutableElement provisionMethod =
+                      MoreElements.asExecutable(contributionBinding.bindingElement());
+                  incompatiblyScopedMethodsBuilder.add(
+                      methodSignatureFormatter.format(provisionMethod));
+                  break;
+                case INJECTION:
+                  incompatiblyScopedMethodsBuilder.add(
+                      bindingScope.getReadableSource()
+                          + " class "
+                          + contributionBinding.bindingTypeElement().getQualifiedName());
+                  break;
+                default:
+                  throw new IllegalStateException();
+              }
+            }
+          }
+        }
+      }
+      ImmutableSet<String> incompatiblyScopedMethods = incompatiblyScopedMethodsBuilder.build();
+      if (!incompatiblyScopedMethods.isEmpty()) {
+        TypeElement componentType = subject.componentDescriptor().componentDefinitionType();
+        StringBuilder message = new StringBuilder(componentType.getQualifiedName());
+        if (componentScope.isPresent()) {
+          message.append(" scoped with ");
+          message.append(componentScope.getReadableSource());
+          message.append(" may not reference bindings with different scopes:\n");
+        } else {
+          message.append(" (unscoped) may not reference scoped bindings:\n");
+        }
+        for (String method : incompatiblyScopedMethods) {
+          message.append(ErrorMessages.INDENT).append(method).append("\n");
+        }
+        reportBuilder.addError(
+            message.toString(), componentType, subject.componentDescriptor().componentAnnotation());
+      }
+    }
+
+    @SuppressWarnings("resource") // Appendable is a StringBuilder.
+    private void reportProviderMayNotDependOnProducer(Deque<ResolvedRequest> path) {
+      StringBuilder errorMessage = new StringBuilder();
+      if (path.size() == 1) {
+        new Formatter(errorMessage)
+            .format(
+                ErrorMessages.PROVIDER_ENTRY_POINT_MAY_NOT_DEPEND_ON_PRODUCER_FORMAT,
+                formatRootRequestKey(path));
+      } else {
+        ImmutableSet<? extends Binding> dependentProvisions =
+            provisionsDependingOnLatestRequest(path);
+        // TODO(beder): Consider displaying all dependent provisions in the error message. If we do
+        // that, should we display all productions that depend on them also?
+        new Formatter(errorMessage).format(ErrorMessages.PROVIDER_MAY_NOT_DEPEND_ON_PRODUCER_FORMAT,
+            keyFormatter.format(dependentProvisions.iterator().next().key()));
+      }
+      reportBuilder.addError(errorMessage.toString(), path.getLast().request().requestElement());
+    }
+
+    private void reportMissingBinding(Deque<ResolvedRequest> path) {
+      Key key = path.peek().request().key();
+      BindingKey bindingKey = path.peek().request().bindingKey();
+      boolean requiresContributionMethod = !key.isValidImplicitProvisionKey(types);
+      boolean requiresProvision = doesPathRequireProvisionOnly(path);
+      StringBuilder errorMessage = new StringBuilder();
+      String requiresErrorMessageFormat = requiresContributionMethod
+          ? requiresProvision
+              ? REQUIRES_PROVIDER_FORMAT
+              : REQUIRES_PROVIDER_OR_PRODUCER_FORMAT
+          : requiresProvision
+              ? REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_FORMAT
+              : REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_OR_PRODUCER_FORMAT;
+      errorMessage.append(String.format(requiresErrorMessageFormat, keyFormatter.format(key)));
+      if (key.isValidMembersInjectionKey()
+          && !injectBindingRegistry.getOrFindMembersInjectionBinding(key).injectionSites()
+              .isEmpty()) {
+        errorMessage.append(" ").append(ErrorMessages.MEMBERS_INJECTION_DOES_NOT_IMPLY_PROVISION);
+      }
+      ImmutableList<String> printableDependencyPath =
+          FluentIterable.from(path)
+              .transform(REQUEST_FROM_RESOLVED_REQUEST)
+              .transform(dependencyRequestFormatter)
+              .filter(Predicates.not(Predicates.equalTo("")))
+              .toList()
+              .reverse();
+      for (String dependency :
+          printableDependencyPath.subList(1, printableDependencyPath.size())) {
+        errorMessage.append('\n').append(dependency);
+      }
+      for (String suggestion : MissingBindingSuggestions.forKey(topLevelGraph, bindingKey)) {
+        errorMessage.append('\n').append(suggestion);
+      }
+      reportBuilder.addError(errorMessage.toString(), path.getLast().request().requestElement());
+    }
+
+    @SuppressWarnings("resource") // Appendable is a StringBuilder.
+    private void reportDuplicateBindings(Deque<ResolvedRequest> path) {
+      ResolvedBindings resolvedBinding = path.peek().binding();
+      StringBuilder builder = new StringBuilder();
+      new Formatter(builder)
+          .format(ErrorMessages.DUPLICATE_BINDINGS_FOR_KEY_FORMAT, formatRootRequestKey(path));
+      for (ContributionBinding binding :
+          Iterables.limit(resolvedBinding.contributionBindings(), DUPLICATE_SIZE_LIMIT)) {
+        builder.append('\n').append(INDENT).append(contributionBindingFormatter.format(binding));
+      }
+      int numberOfOtherBindings =
+          resolvedBinding.contributionBindings().size() - DUPLICATE_SIZE_LIMIT;
+      if (numberOfOtherBindings > 0) {
+        builder.append('\n').append(INDENT)
+            .append("and ").append(numberOfOtherBindings).append(" other");
+      }
+      if (numberOfOtherBindings > 1) {
+        builder.append('s');
+      }
+      reportBuilder.addError(builder.toString(), path.getLast().request().requestElement());
+    }
+
+    @SuppressWarnings("resource") // Appendable is a StringBuilder.
+    private void reportMultipleBindingTypes(Deque<ResolvedRequest> path) {
+      ResolvedBindings resolvedBinding = path.peek().binding();
+      StringBuilder builder = new StringBuilder();
+      new Formatter(builder)
+          .format(ErrorMessages.MULTIPLE_BINDING_TYPES_FOR_KEY_FORMAT, formatRootRequestKey(path));
+      ImmutableListMultimap<ContributionType, ContributionBinding> bindingsByType =
+          ContributionBinding.contributionTypesFor(resolvedBinding.contributionBindings());
+      for (ContributionType type :
+          Ordering.natural().immutableSortedCopy(bindingsByType.keySet())) {
+        builder.append(INDENT);
+        builder.append(formatBindingType(type));
+        builder.append(" bindings:\n");
+        for (ContributionBinding binding : bindingsByType.get(type)) {
+          builder
+              .append(INDENT)
+              .append(INDENT)
+              .append(contributionBindingFormatter.format(binding))
+              .append('\n');
+        }
+      }
+      reportBuilder.addError(builder.toString(), path.getLast().request().requestElement());
+    }
+
+    private void reportDuplicateMapKeys(
+        Deque<ResolvedRequest> path, Collection<ContributionBinding> mapBindings) {
+      StringBuilder builder = new StringBuilder();
+      builder.append(duplicateMapKeysError(formatRootRequestKey(path)));
+      appendBindings(builder, mapBindings, 1);
+      reportBuilder.addError(builder.toString(), path.getLast().request().requestElement());
+    }
+
+    private void reportInconsistentMapKeyAnnotations(
+        Deque<ResolvedRequest> path,
+        Multimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding>
+            mapBindingsByAnnotationType) {
+      StringBuilder builder =
+          new StringBuilder(inconsistentMapKeyAnnotationsError(formatRootRequestKey(path)));
+      for (Map.Entry<Equivalence.Wrapper<DeclaredType>, Collection<ContributionBinding>> entry :
+          mapBindingsByAnnotationType.asMap().entrySet()) {
+        DeclaredType annotationType = entry.getKey().get();
+        Collection<ContributionBinding> bindings = entry.getValue();
+
+        builder
+            .append('\n')
+            .append(INDENT)
+            .append(annotationType)
+            .append(':');
+
+        appendBindings(builder, bindings, 2);
+      }
+      reportBuilder.addError(builder.toString(), path.getLast().request().requestElement());
+    }
+
+    /**
+     * Reports a cycle in the binding path.
+     *
+     * @param bindingPath the binding path, starting with the component provision dependency, and
+     *     ending with the binding that depends on {@code request}
+     * @param request the request that would have been added to the binding path if its
+     *     {@linkplain DependencyRequest#bindingKey() binding key} wasn't already in it
+     * @param indexOfDuplicatedKey the index of the dependency request in {@code bindingPath} whose
+     *     {@linkplain DependencyRequest#bindingKey() binding key} matches {@code request}'s
+     */
+    private void reportCycle(
+        Iterable<ResolvedRequest> bindingPath,
+        DependencyRequest request,
+        int indexOfDuplicatedKey) {
+      ImmutableList<DependencyRequest> requestPath =
+          FluentIterable.from(bindingPath)
+              .transform(REQUEST_FROM_RESOLVED_REQUEST)
+              .append(request)
+              .toList();
+      Element rootRequestElement = requestPath.get(0).requestElement();
+      ImmutableList<DependencyRequest> cycle =
+          requestPath.subList(indexOfDuplicatedKey, requestPath.size());
+      Diagnostic.Kind kind = cycleHasProviderOrLazy(cycle) ? WARNING : ERROR;
+      if (kind == WARNING
+          && (suppressCycleWarnings(rootRequestElement)
+              || suppressCycleWarnings(rootRequestElement.getEnclosingElement())
+              || suppressCycleWarnings(cycle))) {
+        return;
+      }
+      // TODO(cgruber): Provide a hint for the start and end of the cycle.
+      TypeElement componentType = MoreElements.asType(rootRequestElement.getEnclosingElement());
+      reportBuilder.addItem(
+          String.format(
+              ErrorMessages.CONTAINS_DEPENDENCY_CYCLE_FORMAT,
+              componentType.getQualifiedName(),
+              rootRequestElement.getSimpleName(),
+              Joiner.on("\n")
+                  .join(
+                      FluentIterable.from(requestPath)
+                          .transform(dependencyRequestFormatter)
+                          .filter(not(equalTo("")))
+                          .skip(1))),
+          kind,
+          rootRequestElement);
+    }
+
+    /**
+     * Returns {@code true} if any step of a dependency cycle after the first is a {@link Provider}
+     * or {@link Lazy} or a {@code Map<K, Provider<V>>}.
+     *
+     * <p>If an implicit {@link Provider} dependency on {@code Map<K, Provider<V>>} is immediately
+     * preceded by a dependency on {@code Map<K, V>}, which means that the map's {@link Provider}s'
+     * {@link Provider#get() get()} methods are called during provision and so the cycle is not
+     * really broken.
+     */
+    private boolean cycleHasProviderOrLazy(ImmutableList<DependencyRequest> cycle) {
+      DependencyRequest lastDependencyRequest = cycle.get(0);
+      for (DependencyRequest dependencyRequest : skip(cycle, 1)) {
+        switch (dependencyRequest.kind()) {
+          case PROVIDER:
+            if (!isImplicitProviderMapForValueMap(dependencyRequest, lastDependencyRequest)) {
+              return true;
+            }
+            break;
+
+          case LAZY:
+            return true;
+
+          case INSTANCE:
+            if (isMapWithProvidedValues(dependencyRequest.key().type())) {
+              return true;
+            } else {
+              break;
+            }
+
+          default:
+            break;
+        }
+        lastDependencyRequest = dependencyRequest;
+      }
+      return false;
+    }
+
+    /**
+     * Returns {@code true} if {@code maybeValueMapRequest}'s key type is {@code Map<K, V>} and
+     * {@code maybeProviderMapRequest}'s key type is {@code Map<K, Provider<V>>}, and both keys have
+     * the same qualifier.
+     */
+    private boolean isImplicitProviderMapForValueMap(
+        DependencyRequest maybeProviderMapRequest, DependencyRequest maybeValueMapRequest) {
+      TypeMirror maybeProviderMapRequestType = maybeProviderMapRequest.key().type();
+      TypeMirror maybeValueMapRequestType = maybeValueMapRequest.key().type();
+      return maybeProviderMapRequest
+              .key()
+              .wrappedQualifier()
+              .equals(maybeValueMapRequest.key().wrappedQualifier())
+          && isMapWithProvidedValues(maybeProviderMapRequestType)
+          && isMapWithNonProvidedValues(maybeValueMapRequestType)
+          && types.isSameType(
+              getKeyTypeOfMap(asDeclared(maybeProviderMapRequestType)),
+              getKeyTypeOfMap(asDeclared(maybeValueMapRequestType)))
+          && types.isSameType(
+              getProvidedValueTypeOfMap(asDeclared(maybeProviderMapRequestType)),
+              getValueTypeOfMap(asDeclared(maybeValueMapRequestType)));
+    }
+  }
+
+  private boolean suppressCycleWarnings(Element requestElement) {
+    SuppressWarnings suppressions = requestElement.getAnnotation(SuppressWarnings.class);
+    return suppressions != null && Arrays.asList(suppressions.value()).contains("dependency-cycle");
+  }
+
+  private boolean suppressCycleWarnings(ImmutableList<DependencyRequest> pathElements) {
+    for (DependencyRequest dependencyRequest : pathElements) {
+      if (suppressCycleWarnings(dependencyRequest.requestElement())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  ValidationReport<TypeElement> validate(BindingGraph subject) {
+    Validation validation = new Validation(subject);
+    validation.validateSubgraph();
+    return validation.buildReport();
+  }
+
+  /**
+   * Append and format a list of indented component types (with their scope annotations)
+   */
+  private void appendIndentedComponentsList(StringBuilder message, Iterable<TypeElement> types) {
+    for (TypeElement scopedComponent : types) {
+      message.append(INDENT);
+      Scope scope = Scope.scopeOf(scopedComponent);
+      if (scope.isPresent()) {
+        message.append(scope.getReadableSource()).append(' ');
+      }
+      message.append(stripCommonTypePrefixes(scopedComponent.getQualifiedName().toString()))
+          .append('\n');
+    }
+  }
+
+  /**
+   * Returns a set of type elements containing only those found in the input set that have
+   * a scoping annotation.
+   */
+  private ImmutableSet<TypeElement> scopedTypesIn(Set<TypeElement> types) {
+    return FluentIterable.from(types).filter(new Predicate<TypeElement>() {
+      @Override public boolean apply(TypeElement input) {
+        return Scope.scopeOf(input).isPresent();
+      }
+    }).toSet();
+  }
+
+  /**
+   * Returns whether the given dependency path would require the most recent request to be resolved
+   * by only provision bindings.
+   */
+  private boolean doesPathRequireProvisionOnly(Deque<ResolvedRequest> path) {
+    if (path.size() == 1) {
+      // if this is an entry-point, then we check the request
+      switch (path.peek().request().kind()) {
+        case INSTANCE:
+        case PROVIDER:
+        case LAZY:
+        case MEMBERS_INJECTOR:
+          return true;
+        case PRODUCER:
+        case PRODUCED:
+        case FUTURE:
+          return false;
+        default:
+          throw new AssertionError();
+      }
+    }
+    // otherwise, the second-most-recent bindings determine whether the most recent one must be a
+    // provision
+    return !provisionsDependingOnLatestRequest(path).isEmpty();
+  }
+
+  /**
+   * Returns any provision bindings resolved for the second-most-recent request in the given path;
+   * that is, returns those provision bindings that depend on the latest request in the path.
+   */
+  private ImmutableSet<? extends Binding> provisionsDependingOnLatestRequest(
+      Deque<ResolvedRequest> path) {
+    Iterator<ResolvedRequest> iterator = path.iterator();
+    final DependencyRequest request = iterator.next().request();
+    ResolvedRequest previousResolvedRequest = iterator.next();
+    return FluentIterable.from(previousResolvedRequest.binding().bindings())
+        .filter(Binding.Type.PROVISION)
+        .filter(
+            new Predicate<Binding>() {
+              @Override
+              public boolean apply(Binding binding) {
+                return binding.implicitDependencies().contains(request);
+              }
+            })
+        .toSet();
+  }
+
+  private String formatBindingType(ContributionType type) {
+    switch (type) {
+      case MAP:
+        return "Map";
+      case SET:
+        return "Set";
+      case UNIQUE:
+        return "Unique";
+      default:
+        throw new IllegalStateException("Unknown binding type: " + type);
+    }
+  }
+
+  private String formatRootRequestKey(Deque<ResolvedRequest> path) {
+    return keyFormatter.format(path.peek().request().key());
+  }
+
+  private void appendBindings(
+      StringBuilder builder, Collection<ContributionBinding> bindings, int indentLevel) {
+    for (ContributionBinding binding : Iterables.limit(bindings, DUPLICATE_SIZE_LIMIT)) {
+      builder.append('\n');
+      for (int i = 0; i < indentLevel; i++) {
+        builder.append(INDENT);
+      }
+      builder.append(contributionBindingFormatter.format(binding));
+    }
+    int numberOfOtherBindings = bindings.size() - DUPLICATE_SIZE_LIMIT;
+    if (numberOfOtherBindings > 0) {
+      builder.append('\n');
+      for (int i = 0; i < indentLevel; i++) {
+        builder.append(INDENT);
+      }
+      builder.append("and ").append(numberOfOtherBindings).append(" other");
+    }
+    if (numberOfOtherBindings > 1) {
+      builder.append('s');
+    }
+  }
+
+  @AutoValue
+  abstract static class ResolvedRequest {
+    abstract DependencyRequest request();
+    abstract ResolvedBindings binding();
+
+    static ResolvedRequest create(DependencyRequest request, BindingGraph graph) {
+      BindingKey bindingKey = request.bindingKey();
+      ResolvedBindings resolvedBindings = graph.resolvedBindings().get(bindingKey);
+      return new AutoValue_BindingGraphValidator_ResolvedRequest(
+          request,
+          resolvedBindings == null
+              ? ResolvedBindings.noBindings(bindingKey, graph.componentDescriptor())
+              : resolvedBindings);
+    }
+  }
+
+  private static final Function<ResolvedRequest, DependencyRequest> REQUEST_FROM_RESOLVED_REQUEST =
+      new Function<ResolvedRequest, DependencyRequest>() {
+        @Override public DependencyRequest apply(ResolvedRequest resolvedRequest) {
+          return resolvedRequest.request();
+        }
+      };
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingKey.java b/compiler/src/main/java/dagger/internal/codegen/BindingKey.java
new file mode 100644
index 0000000..cd29d8d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/BindingKey.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.value.AutoValue;
+
+/**
+ * A value object that pairs a {@link Key} with the style of its binding (i.e., whether it's a
+ * members injector or normal contribution).
+ *
+ *  @author Gregory Kick
+ *  @since 2.0
+ */
+@AutoValue
+abstract class BindingKey {
+  /** The style of binding that makes a {@link Key} available. */
+  enum Kind {
+    CONTRIBUTION, MEMBERS_INJECTION;
+  }
+
+  static BindingKey create(Kind kind, Key key) {
+    return new AutoValue_BindingKey(kind, key);
+  }
+
+  abstract Kind kind();
+  abstract Key key();
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/BuilderValidator.java b/compiler/src/main/java/dagger/internal/codegen/BuilderValidator.java
new file mode 100644
index 0000000..ba96ebf
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/BuilderValidator.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * Validates {@link dagger.Component.Builder} annotations.
+ *
+ * @author sameb@google.com (Sam Berlin)
+ */
+class BuilderValidator {
+  private final Elements elements;
+  private final Types types;
+  private final ComponentDescriptor.Kind componentType;
+
+  BuilderValidator(Elements elements, Types types, ComponentDescriptor.Kind componentType) {
+    this.elements = elements;
+    this.types = types;
+    this.componentType = componentType;
+  }
+
+  public ValidationReport<TypeElement> validate(TypeElement subject) {
+    ValidationReport.Builder<TypeElement> builder = ValidationReport.about(subject);
+
+    Element componentElement = subject.getEnclosingElement();
+    ErrorMessages.ComponentBuilderMessages msgs = ErrorMessages.builderMsgsFor(componentType);
+    Class<? extends Annotation> componentAnnotation = componentType.annotationType();
+    Class<? extends Annotation> builderAnnotation = componentType.builderAnnotationType();
+    checkArgument(subject.getAnnotation(builderAnnotation) != null);
+
+    if (!isAnnotationPresent(componentElement, componentAnnotation)) {
+      builder.addError(msgs.mustBeInComponent(), subject);
+    }
+
+    switch (subject.getKind()) {
+      case CLASS:
+        List<? extends Element> allElements = subject.getEnclosedElements();
+        List<ExecutableElement> cxtors = ElementFilter.constructorsIn(allElements);
+        if (cxtors.size() != 1 || getOnlyElement(cxtors).getParameters().size() != 0) {
+          builder.addError(msgs.cxtorOnlyOneAndNoArgs(), subject);
+        }
+        break;
+      case INTERFACE:
+        break;
+      default:
+        // If not the correct type, exit early since the rest of the messages will be bogus.
+        builder.addError(msgs.mustBeClassOrInterface(), subject);
+        return builder.build();
+    }
+
+    if (!subject.getTypeParameters().isEmpty()) {
+      builder.addError(msgs.generics(), subject);
+    }
+
+    Set<Modifier> modifiers = subject.getModifiers();
+    if (modifiers.contains(PRIVATE)) {
+      builder.addError(msgs.isPrivate(), subject);
+    }
+    if (!modifiers.contains(STATIC)) {
+      builder.addError(msgs.mustBeStatic(), subject);
+    }
+    // Note: Must be abstract, so no need to check for final.
+    if (!modifiers.contains(ABSTRACT)) {
+      builder.addError(msgs.mustBeAbstract(), subject);
+    }
+
+    ExecutableElement buildMethod = null;
+    Multimap<Equivalence.Wrapper<TypeMirror>, ExecutableElement> methodsPerParam =
+        LinkedHashMultimap.create();
+    for (ExecutableElement method : Util.getUnimplementedMethods(elements, subject)) {
+      ExecutableType resolvedMethodType =
+          MoreTypes.asExecutable(types.asMemberOf(MoreTypes.asDeclared(subject.asType()), method));
+      TypeMirror returnType = resolvedMethodType.getReturnType();
+      if (method.getParameters().size() == 0) {
+        // If this is potentially a build() method, validate it returns the correct type.
+        if (types.isSameType(returnType, componentElement.asType())) {
+          if (buildMethod != null) {
+            // If we found more than one build-like method, fail.
+            error(builder, method, msgs.twoBuildMethods(), msgs.inheritedTwoBuildMethods(),
+                buildMethod);
+          }
+        } else {
+          error(builder, method, msgs.buildMustReturnComponentType(),
+              msgs.inheritedBuildMustReturnComponentType());
+        }
+        // We set the buildMethod regardless of the return type to reduce error spam.
+        buildMethod = method;
+      } else if (method.getParameters().size() > 1) {
+        // If this is a setter, make sure it has one arg.
+        error(builder, method, msgs.methodsMustTakeOneArg(), msgs.inheritedMethodsMustTakeOneArg());
+      } else if (returnType.getKind() != TypeKind.VOID
+          && !types.isSubtype(subject.asType(), returnType)) {
+        // If this correctly had one arg, make sure the return types are valid.
+        error(builder, method, msgs.methodsMustReturnVoidOrBuilder(),
+            msgs.inheritedMethodsMustReturnVoidOrBuilder());
+      } else {
+        // If the return types are valid, record the method.
+        methodsPerParam.put(
+            MoreTypes.equivalence().<TypeMirror>wrap(
+                Iterables.getOnlyElement(resolvedMethodType.getParameterTypes())),
+            method);
+      }
+
+      if (!method.getTypeParameters().isEmpty()) {
+        error(builder, method, msgs.methodsMayNotHaveTypeParameters(),
+            msgs.inheritedMethodsMayNotHaveTypeParameters());
+      }
+    }
+
+    if (buildMethod == null) {
+      builder.addError(msgs.missingBuildMethod(), subject);
+    }
+
+    // Go back through each recorded method per param type.  If we had more than one method
+    // for a given param, fail.
+    for (Map.Entry<Equivalence.Wrapper<TypeMirror>, Collection<ExecutableElement>> entry :
+        methodsPerParam.asMap().entrySet()) {
+      if (entry.getValue().size() > 1) {
+        TypeMirror type = entry.getKey().get();
+        builder.addError(String.format(msgs.manyMethodsForType(), type, entry.getValue()), subject);
+      }
+    }
+
+    // Note: there's more validation in BindingGraphValidator,
+    // specifically to make sure the setter methods mirror the deps.
+
+    return builder.build();
+  }
+
+  /**
+   * Generates one of two error messages. If the method is enclosed in the subject, we target the
+   * error to the method itself. Otherwise we target the error to the subject and list the method as
+   * an argumnent. (Otherwise we have no way of knowing if the method is being compiled in this pass
+   * too, so javac might not be able to pinpoint it's line of code.)
+   */
+  /*
+   * For Component.Builder, the prototypical example would be if someone had:
+   *    libfoo: interface SharedBuilder { void badSetter(A a, B b); }
+   *    libbar: BarComponent { BarBuilder extends SharedBuilder } }
+   * ... the compiler only validates BarBuilder when compiling libbar, but it fails because
+   * of libfoo's SharedBuilder (which could have been compiled in a previous pass).
+   * So we can't point to SharedBuilder#badSetter as the subject of the BarBuilder validation
+   * failure.
+   *
+   * This check is a little more strict than necessary -- ideally we'd check if method's enclosing
+   * class was included in this compile run.  But that's hard, and this is close enough.
+   */
+  private void error(
+      ValidationReport.Builder<TypeElement> builder,
+      ExecutableElement method,
+      String enclosedError,
+      String inheritedError,
+      Object... extraArgs) {
+    if (method.getEnclosingElement().equals(builder.getSubject())) {
+      builder.addError(String.format(enclosedError, extraArgs), method);
+    } else {
+      Object[] newArgs = new Object[extraArgs.length + 1];
+      newArgs[0] = method;
+      System.arraycopy(extraArgs, 0, newArgs, 1, extraArgs.length);
+      builder.addError(String.format(inheritedError, newArgs), builder.getSubject());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentDescriptor.java b/compiler/src/main/java/dagger/internal/codegen/ComponentDescriptor.java
new file mode 100644
index 0000000..650fb9d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentDescriptor.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Component;
+import dagger.Lazy;
+import dagger.MembersInjector;
+import dagger.Module;
+import dagger.Subcomponent;
+import dagger.producers.ProductionComponent;
+import java.lang.annotation.Annotation;
+import java.util.EnumSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import javax.inject.Provider;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.collect.Iterables.getOnlyElement;
+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.isComponent;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.VOID;
+
+/**
+ * The logical representation of a {@link Component} or {@link ProductionComponent} definition.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@AutoValue
+abstract class ComponentDescriptor {
+  ComponentDescriptor() {}
+
+  enum Kind {
+    COMPONENT(Component.class, Component.Builder.class, true),
+    SUBCOMPONENT(Subcomponent.class, Subcomponent.Builder.class, false),
+    PRODUCTION_COMPONENT(ProductionComponent.class, ProductionComponent.Builder.class, true);
+
+    private final Class<? extends Annotation> annotationType;
+    private final Class<? extends Annotation> builderType;
+    private final boolean isTopLevel;
+
+    /**
+     * Returns the kind of an annotated element if it is annotated with one of the
+     * {@linkplain #annotationType() annotation types}.
+     *
+     * @throws IllegalArgumentException if the element is annotated with more than one of the
+     *     annotation types
+     */
+    static Optional<Kind> forAnnotatedElement(TypeElement element) {
+      Set<Kind> kinds = EnumSet.noneOf(Kind.class);
+      for (Kind kind : values()) {
+        if (MoreElements.isAnnotationPresent(element, kind.annotationType())) {
+          kinds.add(kind);
+        }
+      }
+      checkArgument(
+          kinds.size() <= 1, "%s cannot be annotated with more than one of %s", element, kinds);
+      return Optional.fromNullable(getOnlyElement(kinds, null));
+    }
+
+    Kind(
+        Class<? extends Annotation> annotationType,
+        Class<? extends Annotation> builderType,
+        boolean isTopLevel) {
+      this.annotationType = annotationType;
+      this.builderType = builderType;
+      this.isTopLevel = isTopLevel;
+    }
+
+    Class<? extends Annotation> annotationType() {
+      return annotationType;
+    }
+
+    Class<? extends Annotation> builderAnnotationType() {
+      return builderType;
+    }
+
+    boolean isTopLevel() {
+      return isTopLevel;
+    }
+  }
+
+  abstract Kind kind();
+
+  abstract AnnotationMirror componentAnnotation();
+
+  /**
+   * The type (interface or abstract class) that defines the component. This is the element to which
+   * the {@link Component} annotation was applied.
+   */
+  abstract TypeElement componentDefinitionType();
+
+  /**
+   * The set of component dependencies listed in {@link Component#dependencies}.
+   */
+  abstract ImmutableSet<TypeElement> dependencies();
+
+  /**
+   * The set of {@link ModuleDescriptor modules} declared directly in {@link Component#modules}.
+   * Use {@link #transitiveModules} to get the full set of modules available upon traversing
+   * {@link Module#includes}.
+   */
+  abstract ImmutableSet<ModuleDescriptor> modules();
+
+  /**
+   * Returns the set of {@link ModuleDescriptor modules} declared in {@link Component#modules} and
+   * those reachable by traversing {@link Module#includes}.
+   *
+   * <p>Note that for subcomponents this <em>will not</em> include descriptors for any modules that
+   * are declared in parent components.
+   */
+  ImmutableSet<ModuleDescriptor> transitiveModules() {
+    Set<ModuleDescriptor> transitiveModules = new LinkedHashSet<>();
+    for (ModuleDescriptor module : modules()) {
+      addTransitiveModules(transitiveModules, module);
+    }
+    return ImmutableSet.copyOf(transitiveModules);
+  }
+
+  ImmutableSet<TypeElement> transitiveModuleTypes() {
+    return FluentIterable.from(transitiveModules())
+        .transform(ModuleDescriptor.getModuleElement())
+        .toSet();
+  }
+
+  private static Set<ModuleDescriptor> addTransitiveModules(
+      Set<ModuleDescriptor> transitiveModules, ModuleDescriptor module) {
+    if (transitiveModules.add(module)) {
+      for (ModuleDescriptor includedModule : module.includedModules()) {
+        addTransitiveModules(transitiveModules, includedModule);
+      }
+    }
+    return transitiveModules;
+  }
+
+  /**
+   * An index of the type to which this component holds a reference (the type listed in
+   * {@link Component#dependencies} or {@link ProductionComponent#dependencies} as opposed to the
+   * enclosing type) for each method from a component dependency that can be used for binding.
+   */
+  abstract ImmutableMap<ExecutableElement, TypeElement> dependencyMethodIndex();
+
+  /**
+   * The element representing {@link Executor}, if it should be a dependency of this component.
+   */
+  abstract Optional<TypeElement> executorDependency();
+
+  /**
+   * The scope of the component.
+   */
+  abstract Scope scope();
+
+  abstract ImmutableMap<ComponentMethodDescriptor, ComponentDescriptor> subcomponents();
+
+  abstract ImmutableSet<ComponentMethodDescriptor> componentMethods();
+
+  // TODO(gak): Consider making this non-optional and revising the
+  // interaction between the spec & generation
+  abstract Optional<BuilderSpec> builderSpec();
+
+  @AutoValue
+  static abstract class ComponentMethodDescriptor {
+    abstract ComponentMethodKind kind();
+    abstract Optional<DependencyRequest> dependencyRequest();
+    abstract ExecutableElement methodElement();
+    
+    /**
+     * A predicate that passes for {@link ComponentMethodDescriptor}s of a given kind.
+     */
+    static Predicate<ComponentMethodDescriptor> isOfKind(final ComponentMethodKind kind) {
+      return new Predicate<ComponentMethodDescriptor>() {
+        @Override
+        public boolean apply(ComponentMethodDescriptor descriptor) {
+          return kind.equals(descriptor.kind());
+        }
+      };
+    }
+  }
+
+  enum ComponentMethodKind {
+    PROVISON,
+    PRODUCTION,
+    MEMBERS_INJECTION,
+    SUBCOMPONENT,
+    SUBCOMPONENT_BUILDER,
+  }
+  
+  @AutoValue
+  static abstract class BuilderSpec {
+    abstract TypeElement builderDefinitionType();
+    abstract Map<TypeElement, ExecutableElement> methodMap();
+    abstract ExecutableElement buildMethod();
+    abstract TypeMirror componentType();
+  }
+
+  static final class Factory {
+    private final Elements elements;
+    private final Types types;
+    private final DependencyRequest.Factory dependencyRequestFactory;
+    private final ModuleDescriptor.Factory moduleDescriptorFactory;
+
+    Factory(
+        Elements elements,
+        Types types,
+        DependencyRequest.Factory dependencyRequestFactory,
+        ModuleDescriptor.Factory moduleDescriptorFactory) {
+      this.elements = elements;
+      this.types = types;
+      this.dependencyRequestFactory = dependencyRequestFactory;
+      this.moduleDescriptorFactory = moduleDescriptorFactory;
+    }
+
+    /**
+     * Returns a component descriptor for a type annotated with either {@link Component @Component}
+     * or {@link ProductionComponent @ProductionComponent}.
+     */
+    ComponentDescriptor forComponent(TypeElement componentDefinitionType) {
+      Optional<Kind> kind = Kind.forAnnotatedElement(componentDefinitionType);
+      checkArgument(
+          kind.isPresent() && kind.get().isTopLevel(),
+          "%s must be annotated with @Component or @ProductionComponent",
+          componentDefinitionType);
+      return create(componentDefinitionType, kind.get());
+    }
+
+    private ComponentDescriptor create(TypeElement componentDefinitionType, Kind kind) {
+      DeclaredType declaredComponentType = MoreTypes.asDeclared(componentDefinitionType.asType());
+      AnnotationMirror componentMirror =
+          getAnnotationMirror(componentDefinitionType, kind.annotationType())
+              .or(getAnnotationMirror(componentDefinitionType, Subcomponent.class))
+              .get();
+      ImmutableSet<TypeElement> componentDependencyTypes =
+          isComponent(componentDefinitionType)
+              ? MoreTypes.asTypeElements(getComponentDependencies(componentMirror))
+              : ImmutableSet.<TypeElement>of();
+
+      ImmutableMap.Builder<ExecutableElement, TypeElement> dependencyMethodIndex =
+          ImmutableMap.builder();
+
+      for (TypeElement componentDependency : componentDependencyTypes) {
+        List<ExecutableElement> dependencyMethods =
+            ElementFilter.methodsIn(elements.getAllMembers(componentDependency));
+        for (ExecutableElement dependencyMethod : dependencyMethods) {
+          if (isComponentContributionMethod(elements, dependencyMethod)) {
+            dependencyMethodIndex.put(dependencyMethod, componentDependency);
+          }
+        }
+      }
+
+      Optional<TypeElement> executorDependency =
+          kind.equals(Kind.PRODUCTION_COMPONENT)
+              ? Optional.of(elements.getTypeElement(Executor.class.getCanonicalName()))
+              : Optional.<TypeElement>absent();
+
+      ImmutableSet.Builder<ModuleDescriptor> modules = ImmutableSet.builder();
+      for (TypeMirror moduleIncludesType : getComponentModules(componentMirror)) {
+        modules.add(moduleDescriptorFactory.create(MoreTypes.asTypeElement(moduleIncludesType)));
+      }
+      if (kind.equals(Kind.PRODUCTION_COMPONENT)) {
+        modules.add(descriptorForMonitoringModule(componentDefinitionType));
+      }
+
+      ImmutableSet<ExecutableElement> unimplementedMethods =
+          Util.getUnimplementedMethods(elements, componentDefinitionType);
+
+      ImmutableSet.Builder<ComponentMethodDescriptor> componentMethodsBuilder =
+          ImmutableSet.builder();
+
+      ImmutableMap.Builder<ComponentMethodDescriptor, ComponentDescriptor> subcomponentDescriptors =
+          ImmutableMap.builder();
+      for (ExecutableElement componentMethod : unimplementedMethods) {
+        ExecutableType resolvedMethod =
+            MoreTypes.asExecutable(types.asMemberOf(declaredComponentType, componentMethod));
+        ComponentMethodDescriptor componentMethodDescriptor =
+            getDescriptorForComponentMethod(componentDefinitionType, kind, componentMethod);
+        componentMethodsBuilder.add(componentMethodDescriptor);
+        switch (componentMethodDescriptor.kind()) {
+          case SUBCOMPONENT:
+            subcomponentDescriptors.put(
+                componentMethodDescriptor,
+                create(
+                    MoreElements.asType(MoreTypes.asElement(resolvedMethod.getReturnType())),
+                    Kind.SUBCOMPONENT));
+            break;
+          case SUBCOMPONENT_BUILDER:
+            subcomponentDescriptors.put(
+                componentMethodDescriptor,
+                create(
+                    MoreElements.asType(
+                        MoreTypes.asElement(resolvedMethod.getReturnType()).getEnclosingElement()),
+                    Kind.SUBCOMPONENT));
+            break;
+          default: // nothing special to do for other methods.
+        }
+
+      }
+
+      ImmutableList<DeclaredType> enclosedBuilders = kind.builderAnnotationType() == null
+          ? ImmutableList.<DeclaredType>of()
+          : enclosedBuilders(componentDefinitionType, kind.builderAnnotationType());
+      Optional<DeclaredType> builderType =
+          Optional.fromNullable(getOnlyElement(enclosedBuilders, null));
+
+      Scope scope = Scope.scopeOf(componentDefinitionType);
+      return new AutoValue_ComponentDescriptor(
+          kind,
+          componentMirror,
+          componentDefinitionType,
+          componentDependencyTypes,
+          modules.build(),
+          dependencyMethodIndex.build(),
+          executorDependency,
+          scope,
+          subcomponentDescriptors.build(),
+          componentMethodsBuilder.build(),
+          createBuilderSpec(builderType));
+    }
+
+    private ComponentMethodDescriptor getDescriptorForComponentMethod(TypeElement componentElement,
+        Kind componentKind,
+        ExecutableElement componentMethod) {
+      ExecutableType resolvedComponentMethod = MoreTypes.asExecutable(types.asMemberOf(
+          MoreTypes.asDeclared(componentElement.asType()), componentMethod));
+      TypeMirror returnType = resolvedComponentMethod.getReturnType();
+      if (returnType.getKind().equals(DECLARED)) {
+        if (MoreTypes.isTypeOf(Provider.class, returnType)
+            || MoreTypes.isTypeOf(Lazy.class, returnType)) {
+          return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+              ComponentMethodKind.PROVISON,
+              Optional.of(dependencyRequestFactory.forComponentProvisionMethod(componentMethod,
+                  resolvedComponentMethod)),
+              componentMethod);
+        } else if (MoreTypes.isTypeOf(MembersInjector.class, returnType)) {
+          return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+              ComponentMethodKind.MEMBERS_INJECTION,
+              Optional.of(dependencyRequestFactory.forComponentMembersInjectionMethod(
+                  componentMethod,
+                  resolvedComponentMethod)),
+              componentMethod);
+        } else if (isAnnotationPresent(MoreTypes.asElement(returnType), Subcomponent.class)) {
+          return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+              ComponentMethodKind.SUBCOMPONENT,
+              Optional.<DependencyRequest>absent(),
+              componentMethod);
+        } else if (isAnnotationPresent(MoreTypes.asElement(returnType),
+            Subcomponent.Builder.class)) {
+          return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+              ComponentMethodKind.SUBCOMPONENT_BUILDER,
+              Optional.<DependencyRequest>absent(),
+              componentMethod);
+        }
+      }
+
+      // a typical provision method
+      if (componentMethod.getParameters().isEmpty()
+          && !componentMethod.getReturnType().getKind().equals(VOID)) {
+        switch (componentKind) {
+          case COMPONENT:
+          case SUBCOMPONENT:
+            return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+                ComponentMethodKind.PROVISON,
+                Optional.of(dependencyRequestFactory.forComponentProvisionMethod(componentMethod,
+                    resolvedComponentMethod)),
+                componentMethod);
+          case PRODUCTION_COMPONENT:
+            return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+                ComponentMethodKind.PRODUCTION,
+                Optional.of(dependencyRequestFactory.forComponentProductionMethod(componentMethod,
+                    resolvedComponentMethod)),
+                componentMethod);
+          default:
+            throw new AssertionError();
+        }
+      }
+
+      List<? extends TypeMirror> parameterTypes = resolvedComponentMethod.getParameterTypes();
+      if (parameterTypes.size() == 1
+          && (returnType.getKind().equals(VOID)
+              || MoreTypes.equivalence().equivalent(returnType, parameterTypes.get(0)))) {
+        return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor(
+            ComponentMethodKind.MEMBERS_INJECTION,
+            Optional.of(dependencyRequestFactory.forComponentMembersInjectionMethod(
+                componentMethod,
+                resolvedComponentMethod)),
+            componentMethod);
+      }
+
+      throw new IllegalArgumentException("not a valid component method: " + componentMethod);
+    }
+
+    private Optional<BuilderSpec> createBuilderSpec(Optional<DeclaredType> builderType) {
+      if (!builderType.isPresent()) {
+        return Optional.absent();
+      }
+      TypeElement element = MoreTypes.asTypeElement(builderType.get());
+      ImmutableSet<ExecutableElement> methods = Util.getUnimplementedMethods(elements, element);
+      ImmutableMap.Builder<TypeElement, ExecutableElement> map = ImmutableMap.builder();
+      ExecutableElement buildMethod = null;
+      for (ExecutableElement method : methods) {
+        if (method.getParameters().isEmpty()) {
+          buildMethod = method;
+        } else {
+          ExecutableType resolved =
+              MoreTypes.asExecutable(types.asMemberOf(builderType.get(), method));
+          map.put(MoreTypes.asTypeElement(getOnlyElement(resolved.getParameterTypes())), method);
+        }
+      }
+      verify(buildMethod != null); // validation should have ensured this.
+      return Optional.<BuilderSpec>of(new AutoValue_ComponentDescriptor_BuilderSpec(element,
+          map.build(), buildMethod, element.getEnclosingElement().asType()));
+    }
+
+    /**
+     * Returns a descriptor for a generated module that handles monitoring for production
+     * components. This module is generated in the {@link MonitoringModuleProcessingStep}.
+     *
+     * @throws TypeNotPresentException if the module has not been generated yet. This will cause the
+     *     processor to retry in a later processing round.
+     */
+    private ModuleDescriptor descriptorForMonitoringModule(TypeElement componentDefinitionType) {
+      String generatedMonitorModuleName =
+          SourceFiles.generatedMonitoringModuleName(componentDefinitionType).canonicalName();
+      TypeElement monitoringModule = elements.getTypeElement(generatedMonitorModuleName);
+      if (monitoringModule == null) {
+        throw new TypeNotPresentException(generatedMonitorModuleName, null);
+      }
+      return moduleDescriptorFactory.create(monitoringModule);
+    }
+  }
+
+  static boolean isComponentContributionMethod(Elements elements, ExecutableElement method) {
+    return method.getParameters().isEmpty()
+        && !method.getReturnType().getKind().equals(VOID)
+        && !elements.getTypeElement(Object.class.getCanonicalName())
+            .equals(method.getEnclosingElement());
+  }
+
+  static boolean isComponentProductionMethod(Elements elements, ExecutableElement method) {
+    return isComponentContributionMethod(elements, method)
+        && MoreTypes.isTypeOf(ListenableFuture.class, method.getReturnType());
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentGenerator.java b/compiler/src/main/java/dagger/internal/codegen/ComponentGenerator.java
new file mode 100644
index 0000000..72e761c
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentGenerator.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import dagger.Component;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+
+/**
+ * Generates the implementation of the abstract types annotated with {@link Component}.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class ComponentGenerator extends SourceFileGenerator<BindingGraph> {
+  private final Types types;
+  private final Elements elements;
+  private final Key.Factory keyFactory;
+  private final Diagnostic.Kind nullableValidationType;
+
+  ComponentGenerator(
+      Filer filer,
+      Elements elements,
+      Types types,
+      Key.Factory keyFactory,
+      Diagnostic.Kind nullableValidationType) {
+    super(filer);
+    this.types = types;
+    this.elements = elements;
+    this.keyFactory = keyFactory;
+    this.nullableValidationType = nullableValidationType;
+  }
+
+  @Override
+  ClassName nameGeneratedType(BindingGraph input) {
+    ClassName componentDefinitionClassName =
+        ClassName.fromTypeElement(input.componentDescriptor().componentDefinitionType());
+    String componentName = "Dagger" + componentDefinitionClassName.classFileName('_');
+    return componentDefinitionClassName.topLevelClassName().peerNamed(componentName);
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(BindingGraph input) {
+    return ImmutableSet.of(input.componentDescriptor().componentDefinitionType());
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(BindingGraph input) {
+    return Optional.of(input.componentDescriptor().componentDefinitionType());
+  }
+
+  @AutoValue static abstract class MemberSelect {
+    static MemberSelect instanceSelect(ClassName owningClass, Snippet snippet) {
+      return new AutoValue_ComponentGenerator_MemberSelect(
+          Optional.<TypeName> absent(), owningClass, false, snippet);
+    }
+
+    static MemberSelect staticSelect(ClassName owningClass, Snippet snippet) {
+      return new AutoValue_ComponentGenerator_MemberSelect(
+          Optional.<TypeName> absent(), owningClass, true, snippet);
+    }
+
+    static MemberSelect staticMethodInvocationWithCast(
+        ClassName owningClass, Snippet snippet, TypeName castType) {
+      return new AutoValue_ComponentGenerator_MemberSelect(
+          Optional.of(castType), owningClass, true, snippet);
+    }
+
+    /**
+     * This exists only to facilitate edge cases in which we need to select a member, but that
+     * member uses a type parameter that can't be inferred.
+     */
+    abstract Optional<TypeName> selectedCast();
+    abstract ClassName owningClass();
+    abstract boolean staticMember();
+    abstract Snippet snippet();
+
+    private Snippet qualifiedSelectSnippet() {
+      return Snippet.format(
+          "%s" + (staticMember() ? "" : ".this") + ".%s",
+          owningClass(), snippet());
+    }
+
+    Snippet getSnippetWithRawTypeCastFor(ClassName usingClass) {
+      Snippet snippet = getSnippetFor(usingClass);
+      return selectedCast().isPresent()
+          ? Snippet.format("(%s) %s", selectedCast().get(), snippet)
+          : snippet;
+    }
+
+    Snippet getSnippetFor(ClassName usingClass) {
+      return owningClass().equals(usingClass) ? snippet() : qualifiedSelectSnippet();
+    }
+  }
+
+  @Override
+  ImmutableSet<JavaWriter> write(ClassName componentName, BindingGraph input) {
+    return new ComponentWriter(
+            types, elements, keyFactory, nullableValidationType, componentName, input)
+        .write();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentHierarchyValidator.java b/compiler/src/main/java/dagger/internal/codegen/ComponentHierarchyValidator.java
new file mode 100644
index 0000000..8fb4191
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentHierarchyValidator.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import dagger.internal.codegen.ComponentDescriptor.BuilderSpec;
+import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
+import java.util.Map;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+import static com.google.common.base.Functions.constant;
+
+/**
+ * Validates the relationships between parent components and subcomponents.
+ */
+final class ComponentHierarchyValidator {
+  ValidationReport<TypeElement> validate(ComponentDescriptor componentDescriptor) {
+    return validateSubcomponentMethods(
+        componentDescriptor,
+        Maps.toMap(
+            componentDescriptor.transitiveModuleTypes(),
+            constant(componentDescriptor.componentDefinitionType())));
+  }
+
+  private ValidationReport<TypeElement> validateSubcomponentMethods(
+      ComponentDescriptor componentDescriptor,
+      Map<TypeElement, TypeElement> existingModuleToOwners) {
+    ValidationReport.Builder<TypeElement> reportBuilder =
+        ValidationReport.about(componentDescriptor.componentDefinitionType());
+    for (Map.Entry<ComponentMethodDescriptor, ComponentDescriptor> subcomponentEntry :
+        componentDescriptor.subcomponents().entrySet()) {
+      ComponentMethodDescriptor subcomponentMethodDescriptor = subcomponentEntry.getKey();
+      ComponentDescriptor subcomponentDescriptor = subcomponentEntry.getValue();
+      // validate the way that we create subcomponents
+      switch (subcomponentMethodDescriptor.kind()) {
+        case SUBCOMPONENT:
+          for (VariableElement factoryMethodParameter :
+              subcomponentMethodDescriptor.methodElement().getParameters()) {
+            TypeElement origininatingComponent =
+                existingModuleToOwners.get(
+                    MoreTypes.asTypeElement(factoryMethodParameter.asType()));
+            if (origininatingComponent != null) {
+              /* Factory method tries to pass a module that is already present in the parent.
+               * This is an error. */
+              reportBuilder.addError(
+                  String.format(
+                      "This module is present in %s. Subcomponents cannot use an instance of a "
+                          + "module that differs from its parent.",
+                      origininatingComponent.getQualifiedName()),
+                  factoryMethodParameter);
+            }
+          }
+          break;
+        case SUBCOMPONENT_BUILDER:
+          BuilderSpec subcomponentBuilderSpec = subcomponentDescriptor.builderSpec().get();
+          for (Map.Entry<TypeElement, ExecutableElement> builderMethodEntry :
+              subcomponentBuilderSpec.methodMap().entrySet()) {
+            TypeElement origininatingComponent =
+                existingModuleToOwners.get(builderMethodEntry.getKey());
+            if (origininatingComponent != null) {
+              /* A subcomponent builder allows you to pass a module that is already present in the
+               * parent.  This can't be an error because it might be valid in _other_ components, so
+               * we warn here. */
+              ExecutableElement builderMethodElement = builderMethodEntry.getValue();
+              /* TODO(gak): consider putting this on the builder method directly if it's in the
+               * component being compiled */
+              reportBuilder.addWarning(
+                  String.format(
+                      "This module is present in %s. Subcomponents cannot use an instance of a "
+                          + "module that differs from its parent. The implementation of %s "
+                          + "in this component will throw %s.",
+                      origininatingComponent.getQualifiedName(),
+                      builderMethodElement.getSimpleName(),
+                      UnsupportedOperationException.class.getSimpleName()),
+                  builderMethodElement);
+            }
+          }
+          break;
+        default:
+          throw new AssertionError();
+      }
+      reportBuilder.addSubreport(
+          validateSubcomponentMethods(
+              subcomponentDescriptor,
+              new ImmutableMap.Builder<TypeElement, TypeElement>()
+                  .putAll(existingModuleToOwners)
+                  .putAll(
+                      Maps.toMap(
+                          Sets.difference(
+                              subcomponentDescriptor.transitiveModuleTypes(),
+                              existingModuleToOwners.keySet()),
+                          constant(subcomponentDescriptor.componentDefinitionType())))
+                  .build()));
+    }
+    return reportBuilder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/ComponentProcessingStep.java
new file mode 100644
index 0000000..39b21ca
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentProcessingStep.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.auto.common.MoreElements;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.SetMultimap;
+import dagger.Component;
+import dagger.Subcomponent;
+import dagger.internal.codegen.ComponentDescriptor.Factory;
+import dagger.internal.codegen.ComponentValidator.ComponentValidationReport;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * A {@link ProcessingStep} that is responsible for dealing with the {@link Component} annotation
+ * as part of the {@link ComponentProcessor}.
+ *
+ * @author Gregory Kick
+ */
+final class ComponentProcessingStep extends AbstractComponentProcessingStep {
+  private final Messager messager;
+  private final ComponentValidator componentValidator;
+  private final ComponentValidator subcomponentValidator;
+  private final BuilderValidator componentBuilderValidator;
+  private final BuilderValidator subcomponentBuilderValidator;
+
+  ComponentProcessingStep(
+      Messager messager,
+      ComponentValidator componentValidator,
+      ComponentValidator subcomponentValidator,
+      BuilderValidator componentBuilderValidator,
+      BuilderValidator subcomponentBuilderValidator,
+      ComponentHierarchyValidator componentHierarchyValidator,
+      BindingGraphValidator bindingGraphValidator,
+      Factory componentDescriptorFactory,
+      BindingGraph.Factory bindingGraphFactory,
+      ComponentGenerator componentGenerator) {
+    super(
+        Component.class,
+        messager,
+        componentHierarchyValidator,
+        bindingGraphValidator,
+        componentDescriptorFactory,
+        bindingGraphFactory,
+        componentGenerator);
+    this.messager = messager;
+    this.componentValidator = componentValidator;
+    this.subcomponentValidator = subcomponentValidator;
+    this.componentBuilderValidator = componentBuilderValidator;
+    this.subcomponentBuilderValidator = subcomponentBuilderValidator;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.<Class<? extends Annotation>>of(Component.class, Component.Builder.class,
+        Subcomponent.class, Subcomponent.Builder.class);
+  }
+
+  @Override
+  protected ComponentElementValidator componentElementValidator(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    final Map<Element, ValidationReport<TypeElement>> builderReportsByComponent =
+        processComponentBuilders(elementsByAnnotation.get(Component.Builder.class));
+    final Set<Element> subcomponentBuilderElements =
+        elementsByAnnotation.get(Subcomponent.Builder.class);
+    final Map<Element, ValidationReport<TypeElement>> builderReportsBySubcomponent =
+        processSubcomponentBuilders(subcomponentBuilderElements);
+    final Set<Element> subcomponentElements = elementsByAnnotation.get(Subcomponent.class);
+    final Map<Element, ValidationReport<TypeElement>> reportsBySubcomponent =
+        processSubcomponents(subcomponentElements, subcomponentBuilderElements);
+    return new ComponentElementValidator() {
+      @Override
+      boolean validateComponent(TypeElement componentTypeElement, Messager messager) {
+        ComponentValidationReport validationReport =
+            componentValidator.validate(
+                componentTypeElement, subcomponentElements, subcomponentBuilderElements);
+        validationReport.report().printMessagesTo(messager);
+        return isClean(
+            validationReport,
+            builderReportsByComponent,
+            reportsBySubcomponent,
+            builderReportsBySubcomponent);
+      }
+    };
+  }
+
+  private Map<Element, ValidationReport<TypeElement>> processComponentBuilders(
+      Set<? extends Element> componentBuilderElements) {
+    Map<Element, ValidationReport<TypeElement>> builderReportsByComponent = Maps.newHashMap();
+    for (Element element : componentBuilderElements) {
+      ValidationReport<TypeElement> report =
+          componentBuilderValidator.validate(MoreElements.asType(element));
+      report.printMessagesTo(messager);
+      builderReportsByComponent.put(element.getEnclosingElement(), report);
+    }
+    return builderReportsByComponent;
+  }
+
+  private Map<Element, ValidationReport<TypeElement>> processSubcomponentBuilders(
+      Set<? extends Element> subcomponentBuilderElements) {
+    Map<Element, ValidationReport<TypeElement>> builderReportsBySubcomponent = Maps.newHashMap();
+    for (Element element : subcomponentBuilderElements) {
+      ValidationReport<TypeElement> report =
+          subcomponentBuilderValidator.validate(MoreElements.asType(element));
+      report.printMessagesTo(messager);
+      builderReportsBySubcomponent.put(element, report);
+    }
+    return builderReportsBySubcomponent;
+  }
+
+  private Map<Element, ValidationReport<TypeElement>> processSubcomponents(
+      Set<? extends Element> subcomponentElements,
+      Set<? extends Element> subcomponentBuilderElements) {
+    Map<Element, ValidationReport<TypeElement>> reportsBySubcomponent = Maps.newHashMap();
+    for (Element element : subcomponentElements) {
+      ComponentValidationReport report = subcomponentValidator.validate(
+          MoreElements.asType(element), subcomponentElements, subcomponentBuilderElements);
+      report.report().printMessagesTo(messager);
+      reportsBySubcomponent.put(element, report.report());
+    }
+    return reportsBySubcomponent;
+  }
+
+  /**
+   * Returns true if the component's report is clean, its builder report is clean, and all
+   * referenced subcomponent reports & subcomponent builder reports are clean.
+   */
+  private boolean isClean(ComponentValidationReport report,
+      Map<Element, ValidationReport<TypeElement>> builderReportsByComponent,
+      Map<Element, ValidationReport<TypeElement>> reportsBySubcomponent,
+      Map<Element, ValidationReport<TypeElement>> builderReportsBySubcomponent) {
+    Element component = report.report().subject();
+    ValidationReport<?> componentReport = report.report();
+    if (!componentReport.isClean()) {
+      return false;
+    }
+    ValidationReport<?> builderReport = builderReportsByComponent.get(component);
+    if (builderReport != null && !builderReport.isClean()) {
+      return false;
+    }
+    for (Element element : report.referencedSubcomponents()) {
+      ValidationReport<?> subcomponentBuilderReport = builderReportsBySubcomponent.get(element);
+      if (subcomponentBuilderReport != null && !subcomponentBuilderReport.isClean()) {
+        return false;
+      }
+      ValidationReport<?> subcomponentReport = reportsBySubcomponent.get(element);
+      if (subcomponentReport != null && !subcomponentReport.isClean()) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentProcessor.java b/compiler/src/main/java/dagger/internal/codegen/ComponentProcessor.java
new file mode 100644
index 0000000..c35058b
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentProcessor.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor;
+import com.google.auto.service.AutoService;
+import com.google.common.base.Ascii;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import dagger.Module;
+import dagger.Provides;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.lang.annotation.Annotation;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+/**
+ * The annotation processor responsible for generating the classes that drive the Dagger 2.0
+ * implementation.
+ *
+ * TODO(gak): give this some better documentation
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@AutoService(Processor.class)
+public final class ComponentProcessor extends BasicAnnotationProcessor {
+  private InjectBindingRegistry injectBindingRegistry;
+  private FactoryGenerator factoryGenerator;
+  private MembersInjectorGenerator membersInjectorGenerator;
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+
+  @Override
+  public Set<String> getSupportedOptions() {
+    return ImmutableSet.of(
+        DISABLE_INTER_COMPONENT_SCOPE_VALIDATION_KEY,
+        NULLABLE_VALIDATION_KEY,
+        PRIVATE_MEMBER_VALIDATION_TYPE_KEY,
+        STATIC_MEMBER_VALIDATION_TYPE_KEY
+    );
+  }
+
+  @Override
+  protected Iterable<ProcessingStep> initSteps() {
+    Messager messager = processingEnv.getMessager();
+    Types types = processingEnv.getTypeUtils();
+    Elements elements = processingEnv.getElementUtils();
+    Filer filer = processingEnv.getFiler();
+
+    Diagnostic.Kind nullableDiagnosticType =
+        nullableValidationType(processingEnv).diagnosticKind().get();
+
+    MethodSignatureFormatter methodSignatureFormatter = new MethodSignatureFormatter(types);
+    ContributionBindingFormatter contributionBindingFormatter =
+        new ContributionBindingFormatter(methodSignatureFormatter);
+    DependencyRequestFormatter dependencyRequestFormatter = new DependencyRequestFormatter(types);
+    KeyFormatter keyFormatter = new KeyFormatter();
+
+    InjectConstructorValidator injectConstructorValidator = new InjectConstructorValidator();
+    InjectFieldValidator injectFieldValidator = new InjectFieldValidator(
+        privateMemberValidationType(processingEnv).diagnosticKind().get(),
+        staticMemberValidationType(processingEnv).diagnosticKind().get());
+    InjectMethodValidator injectMethodValidator = new InjectMethodValidator(
+        privateMemberValidationType(processingEnv).diagnosticKind().get(),
+        staticMemberValidationType(processingEnv).diagnosticKind().get());
+    ModuleValidator moduleValidator =
+        new ModuleValidator(
+            types,
+            elements,
+            methodSignatureFormatter,
+            Module.class,
+            ImmutableList.<Class<? extends Annotation>>of(Module.class),
+            Provides.class);
+    ProvidesMethodValidator providesMethodValidator = new ProvidesMethodValidator(elements);
+    BuilderValidator componentBuilderValidator =
+        new BuilderValidator(elements, types, ComponentDescriptor.Kind.COMPONENT);
+    BuilderValidator subcomponentBuilderValidator =
+        new BuilderValidator(elements, types, ComponentDescriptor.Kind.SUBCOMPONENT);
+    ComponentValidator subcomponentValidator = ComponentValidator.createForSubcomponent(elements,
+        types, moduleValidator, subcomponentBuilderValidator);
+    ComponentValidator componentValidator = ComponentValidator.createForComponent(elements, types,
+        moduleValidator, subcomponentValidator, subcomponentBuilderValidator);
+    MapKeyValidator mapKeyValidator = new MapKeyValidator();
+    ModuleValidator producerModuleValidator =
+        new ModuleValidator(
+            types,
+            elements,
+            methodSignatureFormatter,
+            ProducerModule.class,
+            ImmutableList.of(Module.class, ProducerModule.class),
+            Produces.class);
+    ProducesMethodValidator producesMethodValidator = new ProducesMethodValidator(elements);
+    ProductionComponentValidator productionComponentValidator = new ProductionComponentValidator();
+    BuilderValidator productionComponentBuilderValidator =
+        new BuilderValidator(elements, types, ComponentDescriptor.Kind.PRODUCTION_COMPONENT);
+
+    Key.Factory keyFactory = new Key.Factory(types, elements);
+
+    this.factoryGenerator =
+        new FactoryGenerator(filer, DependencyRequestMapper.FOR_PROVIDER, nullableDiagnosticType);
+    this.membersInjectorGenerator =
+        new MembersInjectorGenerator(filer, DependencyRequestMapper.FOR_PROVIDER);
+    ComponentGenerator componentGenerator =
+        new ComponentGenerator(filer, elements, types, keyFactory, nullableDiagnosticType);
+    ProducerFactoryGenerator producerFactoryGenerator =
+        new ProducerFactoryGenerator(filer, DependencyRequestMapper.FOR_PRODUCER);
+    MonitoringModuleGenerator monitoringModuleGenerator = new MonitoringModuleGenerator(filer);
+
+    DependencyRequest.Factory dependencyRequestFactory =
+        new DependencyRequest.Factory(elements, keyFactory);
+    ProvisionBinding.Factory provisionBindingFactory =
+        new ProvisionBinding.Factory(elements, types, keyFactory, dependencyRequestFactory);
+    ProductionBinding.Factory productionBindingFactory =
+        new ProductionBinding.Factory(types, keyFactory, dependencyRequestFactory);
+
+    MembersInjectionBinding.Factory membersInjectionBindingFactory =
+        new MembersInjectionBinding.Factory(elements, types, keyFactory, dependencyRequestFactory);
+
+    this.injectBindingRegistry = new InjectBindingRegistry(
+        elements, types, messager, provisionBindingFactory, membersInjectionBindingFactory);
+
+    ModuleDescriptor.Factory moduleDescriptorFactory = new ModuleDescriptor.Factory(
+        elements, provisionBindingFactory, productionBindingFactory);
+
+    ComponentDescriptor.Factory componentDescriptorFactory = new ComponentDescriptor.Factory(
+        elements, types, dependencyRequestFactory, moduleDescriptorFactory);
+
+    BindingGraph.Factory bindingGraphFactory =
+        new BindingGraph.Factory(
+            elements,
+            injectBindingRegistry,
+            keyFactory,
+            provisionBindingFactory,
+            productionBindingFactory);
+
+    MapKeyGenerator mapKeyGenerator = new MapKeyGenerator(filer);
+    ComponentHierarchyValidator componentHierarchyValidator = new ComponentHierarchyValidator();
+    BindingGraphValidator bindingGraphValidator =
+        new BindingGraphValidator(
+            types,
+            injectBindingRegistry,
+            scopeValidationType(processingEnv),
+            nullableDiagnosticType,
+            contributionBindingFormatter,
+            methodSignatureFormatter,
+            dependencyRequestFormatter,
+            keyFormatter);
+
+    return ImmutableList.<ProcessingStep>of(
+        new MapKeyProcessingStep(messager, types, mapKeyValidator, mapKeyGenerator),
+        new InjectProcessingStep(
+            messager,
+            injectConstructorValidator,
+            injectFieldValidator,
+            injectMethodValidator,
+            provisionBindingFactory,
+            membersInjectionBindingFactory,
+            injectBindingRegistry),
+        new MonitoringModuleProcessingStep(messager, monitoringModuleGenerator),
+        new ModuleProcessingStep(
+            messager,
+            moduleValidator,
+            providesMethodValidator,
+            provisionBindingFactory,
+            factoryGenerator),
+        new ComponentProcessingStep(
+            messager,
+            componentValidator,
+            subcomponentValidator,
+            componentBuilderValidator,
+            subcomponentBuilderValidator,
+            componentHierarchyValidator,
+            bindingGraphValidator,
+            componentDescriptorFactory,
+            bindingGraphFactory,
+            componentGenerator),
+        new ProducerModuleProcessingStep(
+            messager,
+            producerModuleValidator,
+            producesMethodValidator,
+            productionBindingFactory,
+            producerFactoryGenerator),
+        new ProductionComponentProcessingStep(
+            messager,
+            productionComponentValidator,
+            productionComponentBuilderValidator,
+            componentHierarchyValidator,
+            bindingGraphValidator,
+            componentDescriptorFactory,
+            bindingGraphFactory,
+            componentGenerator));
+  }
+
+  @Override
+  protected void postProcess() {
+    try {
+      injectBindingRegistry.generateSourcesForRequiredBindings(
+          factoryGenerator, membersInjectorGenerator);
+    } catch (SourceFileGenerationException e) {
+      e.printMessageTo(processingEnv.getMessager());
+    }
+  }
+
+  private static final String DISABLE_INTER_COMPONENT_SCOPE_VALIDATION_KEY =
+      "dagger.disableInterComponentScopeValidation";
+
+  private static final String NULLABLE_VALIDATION_KEY = "dagger.nullableValidation";
+
+  private static final String PRIVATE_MEMBER_VALIDATION_TYPE_KEY =
+      "dagger.privateMemberValidation";
+
+  private static final String STATIC_MEMBER_VALIDATION_TYPE_KEY =
+      "dagger.staticMemberValidation";
+
+  private static ValidationType scopeValidationType(ProcessingEnvironment processingEnv) {
+    return valueOf(processingEnv,
+        DISABLE_INTER_COMPONENT_SCOPE_VALIDATION_KEY,
+        ValidationType.ERROR,
+        EnumSet.allOf(ValidationType.class));
+  }
+
+  private static ValidationType nullableValidationType(ProcessingEnvironment processingEnv) {
+    return valueOf(processingEnv,
+        NULLABLE_VALIDATION_KEY,
+        ValidationType.ERROR,
+        EnumSet.of(ValidationType.ERROR, ValidationType.WARNING));
+  }
+
+  private static ValidationType privateMemberValidationType(ProcessingEnvironment processingEnv) {
+    return valueOf(processingEnv,
+        PRIVATE_MEMBER_VALIDATION_TYPE_KEY,
+        ValidationType.ERROR,
+        EnumSet.of(ValidationType.ERROR, ValidationType.WARNING));
+  }
+
+  private static ValidationType staticMemberValidationType(ProcessingEnvironment processingEnv) {
+    return valueOf(processingEnv,
+        STATIC_MEMBER_VALIDATION_TYPE_KEY,
+        ValidationType.ERROR,
+        EnumSet.of(ValidationType.ERROR, ValidationType.WARNING));
+  }
+
+  private static <T extends Enum<T>> T valueOf(ProcessingEnvironment processingEnv, String key,
+      T defaultValue, Set<T> validValues) {
+    Map<String, String> options = processingEnv.getOptions();
+    if (options.containsKey(key)) {
+      try {
+        T type = Enum.valueOf(
+            defaultValue.getDeclaringClass(),
+            Ascii.toUpperCase(options.get(key)));
+        if (!validValues.contains(type)) {
+          throw new IllegalArgumentException(); // let handler below print out good msg.
+        }
+        return type;
+      } catch (IllegalArgumentException e) {
+        processingEnv.getMessager().printMessage(ERROR, "Processor option -A"
+            + key + " may only have the values " + validValues
+            + " (case insensitive), found: " + options.get(key));
+      }
+    }
+    return defaultValue;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java b/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java
new file mode 100644
index 0000000..a9e82a8
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import dagger.Component;
+import dagger.Module;
+import dagger.Subcomponent;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static dagger.internal.codegen.ConfigurationAnnotations.enclosedBuilders;
+import static dagger.internal.codegen.ConfigurationAnnotations.getComponentModules;
+import static dagger.internal.codegen.ConfigurationAnnotations.getTransitiveModules;
+import static javax.lang.model.element.ElementKind.CLASS;
+import static javax.lang.model.element.ElementKind.INTERFACE;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.type.TypeKind.VOID;
+
+/**
+ * Performs superficial validation of the contract of the {@link Component} annotation.
+ *
+ * @author Gregory Kick
+ */
+final class ComponentValidator {
+  private final Elements elements;
+  private final Types types;
+  private final ComponentDescriptor.Kind componentType;
+  private final ModuleValidator moduleValidator;
+  private final ComponentValidator subcomponentValidator;
+  private final BuilderValidator subcomponentBuilderValidator;
+
+  private ComponentValidator(Elements elements,
+      Types types,
+      ModuleValidator moduleValidator,
+      BuilderValidator subcomponentBuilderValidator) {
+    this.elements = elements;
+    this.types = types;
+    this.componentType = ComponentDescriptor.Kind.SUBCOMPONENT;
+    this.moduleValidator = moduleValidator;
+    this.subcomponentValidator = this;
+    this.subcomponentBuilderValidator = subcomponentBuilderValidator;
+  }
+
+  private ComponentValidator(Elements elements,
+      Types types,
+      ModuleValidator moduleValidator,
+      ComponentValidator subcomponentValidator,
+      BuilderValidator subcomponentBuilderValidator) {
+    this.elements = elements;
+    this.types = types;
+    this.componentType = ComponentDescriptor.Kind.COMPONENT;
+    this.moduleValidator = moduleValidator;
+    this.subcomponentValidator = subcomponentValidator;
+    this.subcomponentBuilderValidator = subcomponentBuilderValidator;
+  }
+
+  static ComponentValidator createForComponent(Elements elements,
+      Types types,
+      ModuleValidator moduleValidator,
+      ComponentValidator subcomponentValidator,
+      BuilderValidator subcomponentBuilderValidator) {
+    return new ComponentValidator(elements,
+        types,
+        moduleValidator,
+        subcomponentValidator,
+        subcomponentBuilderValidator);
+  }
+
+  static ComponentValidator createForSubcomponent(Elements elements,
+      Types types,
+      ModuleValidator moduleValidator,
+      BuilderValidator subcomponentBuilderValidator) {
+    return new ComponentValidator(elements,
+        types,
+        moduleValidator,
+        subcomponentBuilderValidator);
+  }
+
+  @AutoValue
+  static abstract class ComponentValidationReport {
+    abstract Set<Element> referencedSubcomponents();
+    abstract ValidationReport<TypeElement> report();
+  }
+
+  /**
+   * Validates the given component subject. Also validates any referenced subcomponents that aren't
+   * already included in the {@code validatedSubcomponents} set.
+   */
+  public ComponentValidationReport validate(final TypeElement subject,
+      Set<? extends Element> validatedSubcomponents,
+      Set<? extends Element> validatedSubcomponentBuilders) {
+    ValidationReport.Builder<TypeElement> builder = ValidationReport.about(subject);
+
+    if (!subject.getKind().equals(INTERFACE)
+        && !(subject.getKind().equals(CLASS) && subject.getModifiers().contains(ABSTRACT))) {
+      builder.addError(
+          String.format(
+              "@%s may only be applied to an interface or abstract class",
+              componentType.annotationType().getSimpleName()),
+          subject);
+    }
+
+    ImmutableList<DeclaredType> builders =
+        enclosedBuilders(subject, componentType.builderAnnotationType());
+    if (builders.size() > 1) {
+      builder.addError(
+          String.format(ErrorMessages.builderMsgsFor(componentType).moreThanOne(), builders),
+          subject);
+    }
+
+    DeclaredType subjectType = MoreTypes.asDeclared(subject.asType());
+
+    // TODO(gak): This should use Util.findLocalAndInheritedMethods, otherwise
+    // it can return a logical method multiple times (including overrides, etc.)
+    List<? extends Element> members = elements.getAllMembers(subject);
+    Multimap<Element, ExecutableElement> referencedSubcomponents = LinkedHashMultimap.create();
+    for (ExecutableElement method : ElementFilter.methodsIn(members)) {
+      if (method.getModifiers().contains(ABSTRACT)) {
+        ExecutableType resolvedMethod =
+            MoreTypes.asExecutable(types.asMemberOf(subjectType, method));
+        List<? extends TypeMirror> parameterTypes = resolvedMethod.getParameterTypes();
+        List<? extends VariableElement> parameters = method.getParameters();
+        TypeMirror returnType = resolvedMethod.getReturnType();
+
+        // abstract methods are ones we have to implement, so they each need to be validated
+        // first, check the return type.  if it's a subcomponent, validate that method as such.
+        Optional<AnnotationMirror> subcomponentAnnotation =
+            checkForAnnotation(returnType, Subcomponent.class);
+        Optional<AnnotationMirror> subcomponentBuilderAnnotation =
+            checkForAnnotation(returnType, Subcomponent.Builder.class);
+        if (subcomponentAnnotation.isPresent()) {
+          referencedSubcomponents.put(MoreTypes.asElement(returnType), method);
+          validateSubcomponentMethod(builder,
+              method,
+              parameters,
+              parameterTypes,
+              returnType,
+              subcomponentAnnotation);
+        } else if (subcomponentBuilderAnnotation.isPresent()) {
+          referencedSubcomponents.put(MoreTypes.asElement(returnType).getEnclosingElement(),
+              method);
+          validateSubcomponentBuilderMethod(builder,
+              method,
+              parameters,
+              returnType,
+              validatedSubcomponentBuilders);
+        } else {
+          // if it's not a subcomponent...
+          switch (parameters.size()) {
+            case 0:
+              // no parameters means that it is a provision method
+              // basically, there are no restrictions here.  \o/
+              break;
+            case 1:
+              // one parameter means that it's a members injection method
+              TypeMirror onlyParameter = Iterables.getOnlyElement(parameterTypes);
+              if (!(returnType.getKind().equals(VOID)
+                  || types.isSameType(returnType, onlyParameter))) {
+                builder.addError(
+                    "Members injection methods may only return the injected type or void.", method);
+              }
+              break;
+            default:
+              // this isn't any method that we know how to implement...
+              builder.addError(
+                  "This method isn't a valid provision method, members injection method or "
+                      + "subcomponent factory method. Dagger cannot implement this method",
+                  method);
+              break;
+          }
+        }
+      }
+    }
+
+    for (Map.Entry<Element, Collection<ExecutableElement>> entry :
+        referencedSubcomponents.asMap().entrySet()) {
+      if (entry.getValue().size() > 1) {
+        builder.addError(
+            String.format(
+                ErrorMessages.SubcomponentBuilderMessages.INSTANCE.moreThanOneRefToSubcomponent(),
+                entry.getKey(),
+                entry.getValue()),
+            subject);
+      }
+    }
+
+    AnnotationMirror componentMirror =
+        getAnnotationMirror(subject, componentType.annotationType()).get();
+    ImmutableList<TypeMirror> moduleTypes = getComponentModules(componentMirror);
+    moduleValidator.validateReferencedModules(subject, builder, moduleTypes);
+
+    // Make sure we validate any subcomponents we're referencing, unless we know we validated
+    // them already in this pass.
+    // TODO(sameb): If subcomponents refer to each other and both aren't in
+    //              'validatedSubcomponents' (e.g, both aren't compiled in this pass),
+    //              then this can loop forever.
+    ImmutableSet.Builder<Element> allSubcomponents =
+        ImmutableSet.<Element>builder().addAll(referencedSubcomponents.keySet());
+    for (Element subcomponent :
+        Sets.difference(referencedSubcomponents.keySet(), validatedSubcomponents)) {
+      ComponentValidationReport subreport = subcomponentValidator.validate(
+          MoreElements.asType(subcomponent), validatedSubcomponents, validatedSubcomponentBuilders);
+      builder.addItems(subreport.report().items());
+      allSubcomponents.addAll(subreport.referencedSubcomponents());
+    }
+
+    return new AutoValue_ComponentValidator_ComponentValidationReport(allSubcomponents.build(),
+        builder.build());
+  }
+
+  private void validateSubcomponentMethod(final ValidationReport.Builder<TypeElement> builder,
+      ExecutableElement method,
+      List<? extends VariableElement> parameters,
+      List<? extends TypeMirror> parameterTypes,
+      TypeMirror returnType,
+      Optional<AnnotationMirror> subcomponentAnnotation) {
+    ImmutableSet<TypeElement> moduleTypes =
+        MoreTypes.asTypeElements(getComponentModules(subcomponentAnnotation.get()));
+
+    // TODO(gak): This logic maybe/probably shouldn't live here as it requires us to traverse
+    // subcomponents and their modules separately from how it is done in ComponentDescriptor and
+    // ModuleDescriptor
+    @SuppressWarnings("deprecation")
+    ImmutableSet<TypeElement> transitiveModules =
+        getTransitiveModules(types, elements, moduleTypes);
+
+    Set<TypeElement> variableTypes = Sets.newHashSet();
+
+    for (int i = 0; i < parameterTypes.size(); i++) {
+      VariableElement parameter = parameters.get(i);
+      TypeMirror parameterType = parameterTypes.get(i);
+      Optional<TypeElement> moduleType = parameterType.accept(
+          new SimpleTypeVisitor6<Optional<TypeElement>, Void>() {
+            @Override protected Optional<TypeElement> defaultAction(TypeMirror e, Void p) {
+              return Optional.absent();
+            }
+
+            @Override public Optional<TypeElement> visitDeclared(DeclaredType t, Void p) {
+              return MoreElements.isAnnotationPresent(t.asElement(), Module.class)
+                  ? Optional.of(MoreTypes.asTypeElement(t))
+                  : Optional.<TypeElement>absent();
+            }
+          }, null);
+      if (moduleType.isPresent()) {
+        if (variableTypes.contains(moduleType.get())) {
+          builder.addError(
+              String.format(
+                  "A module may only occur once an an argument in a Subcomponent factory "
+                      + "method, but %s was already passed.",
+                  moduleType.get().getQualifiedName()),
+              parameter);
+        }
+        if (!transitiveModules.contains(moduleType.get())) {
+          builder.addError(
+              String.format(
+                  "%s is present as an argument to the %s factory method, but is not one of the"
+                      + " modules used to implement the subcomponent.",
+                  moduleType.get().getQualifiedName(),
+                  MoreTypes.asTypeElement(returnType).getQualifiedName()),
+              method);
+        }
+        variableTypes.add(moduleType.get());
+      } else {
+        builder.addError(
+            String.format(
+                "Subcomponent factory methods may only accept modules, but %s is not.",
+                parameterType),
+            parameter);
+      }
+    }
+  }
+
+  private void validateSubcomponentBuilderMethod(ValidationReport.Builder<TypeElement> builder,
+      ExecutableElement method, List<? extends VariableElement> parameters, TypeMirror returnType,
+      Set<? extends Element> validatedSubcomponentBuilders) {
+
+    if (!parameters.isEmpty()) {
+      builder.addError(
+          ErrorMessages.SubcomponentBuilderMessages.INSTANCE.builderMethodRequiresNoArgs(), method);
+    }
+
+    // If we haven't already validated the subcomponent builder itself, validate it now.
+    TypeElement builderElement = MoreTypes.asTypeElement(returnType);
+    if (!validatedSubcomponentBuilders.contains(builderElement)) {
+      // TODO(sameb): The builder validator right now assumes the element is being compiled
+      // in this pass, which isn't true here.  We should change error messages to spit out
+      // this method as the subject and add the original subject to the message output.
+      builder.addItems(subcomponentBuilderValidator.validate(builderElement).items());
+    }
+  }
+
+  private Optional<AnnotationMirror> checkForAnnotation(TypeMirror type,
+      final Class<? extends Annotation> annotation) {
+    return type.accept(new SimpleTypeVisitor6<Optional<AnnotationMirror>, Void>() {
+      @Override
+      protected Optional<AnnotationMirror> defaultAction(TypeMirror e, Void p) {
+        return Optional.absent();
+      }
+
+      @Override
+      public Optional<AnnotationMirror> visitDeclared(DeclaredType t, Void p) {
+        return MoreElements.getAnnotationMirror(t.asElement(), annotation);
+      }
+    }, null);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentWriter.java b/compiler/src/main/java/dagger/internal/codegen/ComponentWriter.java
new file mode 100644
index 0000000..5221cf0
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ComponentWriter.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import javax.annotation.Generated;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+
+import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * Creates the implementation class for a component.
+ */
+class ComponentWriter extends AbstractComponentWriter {
+
+  ComponentWriter(
+      Types types,
+      Elements elements,
+      Key.Factory keyFactory,
+      Kind nullableValidationType,
+      ClassName name,
+      BindingGraph graph) {
+    super(types, elements, keyFactory, nullableValidationType, name, graph);
+  }
+
+  @Override
+  protected ClassWriter createComponentClass() {
+    JavaWriter javaWriter = JavaWriter.inPackage(name.packageName());
+    javaWriters.add(javaWriter);
+
+    ClassWriter componentWriter = javaWriter.addClass(name.simpleName());
+    componentWriter.annotate(Generated.class).setValue(ComponentProcessor.class.getCanonicalName());
+    componentWriter.addModifiers(PUBLIC, FINAL);
+    componentWriter.setSupertype(componentDefinitionType());
+    return componentWriter;
+  }
+
+  @Override
+  protected ClassWriter createBuilder() {
+    ClassWriter builderWriter = componentWriter.addNestedClass("Builder");
+    builderWriter.addModifiers(STATIC);
+
+    // Only top-level components have the factory builder() method.
+    // Mirror the user's builder API type if they had one.
+    MethodWriter builderFactoryMethod =
+        graph.componentDescriptor().builderSpec().isPresent()
+            ? componentWriter.addMethod(
+                graph
+                    .componentDescriptor()
+                    .builderSpec()
+                    .get()
+                    .builderDefinitionType()
+                    .asType(),
+                "builder")
+            : componentWriter.addMethod(builderWriter, "builder");
+    builderFactoryMethod.addModifiers(PUBLIC, STATIC);
+    builderFactoryMethod.body().addSnippet("return new %s();", builderWriter.name());
+    return builderWriter;
+  }
+
+  @Override
+  protected void addFactoryMethods() {
+    if (canInstantiateAllRequirements()) {
+      MethodWriter factoryMethod =
+          componentWriter.addMethod(componentDefinitionTypeName(), "create");
+      factoryMethod.addModifiers(PUBLIC, STATIC);
+      // TODO(gak): replace this with something that doesn't allocate a builder
+      factoryMethod
+          .body()
+          .addSnippet(
+              "return builder().%s();",
+              graph.componentDescriptor().builderSpec().isPresent()
+                  ? graph
+                      .componentDescriptor()
+                      .builderSpec()
+                      .get()
+                      .buildMethod()
+                      .getSimpleName()
+                  : "build");
+    }
+  }
+
+  /** {@code true} if all of the graph's required dependencies can be automatically constructed. */
+  private boolean canInstantiateAllRequirements() {
+    return Iterables.all(
+        graph.componentRequirements(),
+        new Predicate<TypeElement>() {
+          @Override
+          public boolean apply(TypeElement dependency) {
+            return componentCanMakeNewInstances(dependency);
+          }
+        });
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java b/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java
new file mode 100644
index 0000000..50e3435
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import dagger.Component;
+import dagger.Module;
+import dagger.Subcomponent;
+import dagger.producers.ProducerModule;
+import dagger.producers.ProductionComponent;
+import java.lang.annotation.Annotation;
+import java.util.ArrayDeque;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleAnnotationValueVisitor6;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Utility methods related to dagger configuration annotations (e.g.: {@link Component}
+ * and {@link Module}).
+ *
+ * @author Gregory Kick
+ */
+final class ConfigurationAnnotations {
+
+  static boolean isComponent(TypeElement componentDefinitionType) {
+    return MoreElements.isAnnotationPresent(componentDefinitionType, Component.class)
+        || MoreElements.isAnnotationPresent(componentDefinitionType, ProductionComponent.class);
+  }
+
+  private static final String MODULES_ATTRIBUTE = "modules";
+
+  static ImmutableList<TypeMirror> getComponentModules(AnnotationMirror componentAnnotation) {
+    checkNotNull(componentAnnotation);
+    return convertClassArrayToListOfTypes(componentAnnotation, MODULES_ATTRIBUTE);
+  }
+
+  private static final String DEPENDENCIES_ATTRIBUTE = "dependencies";
+
+  static ImmutableList<TypeMirror> getComponentDependencies(AnnotationMirror componentAnnotation) {
+    checkNotNull(componentAnnotation);
+    return convertClassArrayToListOfTypes(componentAnnotation, DEPENDENCIES_ATTRIBUTE);
+  }
+
+  private static final String INCLUDES_ATTRIBUTE = "includes";
+
+  static ImmutableList<TypeMirror> getModuleIncludes(AnnotationMirror moduleAnnotation) {
+    checkNotNull(moduleAnnotation);
+    return convertClassArrayToListOfTypes(moduleAnnotation, INCLUDES_ATTRIBUTE);
+  }
+
+  private static final String INJECTS_ATTRIBUTE = "injects";
+
+  static ImmutableList<TypeMirror> getModuleInjects(AnnotationMirror moduleAnnotation) {
+    checkNotNull(moduleAnnotation);
+    return convertClassArrayToListOfTypes(moduleAnnotation, INJECTS_ATTRIBUTE);
+  }
+
+  /** Returns the first type that specifies this' nullability, or absent if none. */
+  static Optional<DeclaredType> getNullableType(Element element) {
+    List<? extends AnnotationMirror> mirrors = element.getAnnotationMirrors();
+    for (AnnotationMirror mirror : mirrors) {
+      if (mirror.getAnnotationType().asElement().getSimpleName().toString().equals("Nullable")) {
+        return Optional.of(mirror.getAnnotationType());
+      }
+    }
+    return Optional.absent();
+  }
+
+  /**
+   * Extracts the list of types that is the value of the annotation member {@code elementName} of
+   * {@code annotationMirror}.
+   *
+   * @throws IllegalArgumentException if no such member exists on {@code annotationMirror}, or it
+   *     exists but is not an array
+   * @throws TypeNotPresentException if any of the values cannot be converted to a type
+   */
+  static ImmutableList<TypeMirror> convertClassArrayToListOfTypes(
+      AnnotationMirror annotationMirror, String elementName) {
+    return TO_LIST_OF_TYPES.visit(getAnnotationValue(annotationMirror, elementName), elementName);
+  }
+
+  private static final AnnotationValueVisitor<ImmutableList<TypeMirror>, String> TO_LIST_OF_TYPES =
+      new SimpleAnnotationValueVisitor6<ImmutableList<TypeMirror>, String>() {
+        @Override
+        public ImmutableList<TypeMirror> visitArray(
+            List<? extends AnnotationValue> vals, String elementName) {
+          return FluentIterable.from(vals)
+              .transform(
+                  new Function<AnnotationValue, TypeMirror>() {
+                    @Override
+                    public TypeMirror apply(AnnotationValue typeValue) {
+                      return TO_TYPE.visit(typeValue);
+                    }
+                  })
+              .toList();
+        }
+
+        @Override
+        protected ImmutableList<TypeMirror> defaultAction(Object o, String elementName) {
+          throw new IllegalArgumentException(elementName + " is not an array: " + o);
+        }
+      };
+
+  private static final AnnotationValueVisitor<TypeMirror, Void> TO_TYPE =
+      new SimpleAnnotationValueVisitor6<TypeMirror, Void>() {
+        @Override
+        public TypeMirror visitType(TypeMirror t, Void p) {
+          return t;
+        }
+
+        @Override
+        protected TypeMirror defaultAction(Object o, Void p) {
+          throw new TypeNotPresentException(o.toString(), 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}
+   * is not annotated with {@link Module}, it is ignored.
+   *
+   * @deprecated Use {@link ComponentDescriptor#transitiveModules}.
+   */
+  @Deprecated
+  static ImmutableSet<TypeElement> getTransitiveModules(
+      Types types, Elements elements, Iterable<TypeElement> seedModules) {
+    TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();
+    Queue<TypeElement> moduleQueue = new ArrayDeque<>();
+    Iterables.addAll(moduleQueue, seedModules);
+    Set<TypeElement> moduleElements = Sets.newLinkedHashSet();
+    for (TypeElement moduleElement = moduleQueue.poll();
+        moduleElement != null;
+        moduleElement = moduleQueue.poll()) {
+      Optional<AnnotationMirror> moduleMirror = getAnnotationMirror(moduleElement, Module.class)
+          .or(getAnnotationMirror(moduleElement, ProducerModule.class));
+      if (moduleMirror.isPresent()) {
+        ImmutableSet.Builder<TypeElement> moduleDependenciesBuilder = ImmutableSet.builder();
+        moduleDependenciesBuilder.addAll(
+            MoreTypes.asTypeElements(getModuleIncludes(moduleMirror.get())));
+        // (note: we don't recurse on the parent class because we don't want the parent class as a
+        // root that the component depends on, and also because we want the dependencies rooted
+        // against this element, not the parent.)
+        addIncludesFromSuperclasses(types, moduleElement, moduleDependenciesBuilder, objectType);
+        ImmutableSet<TypeElement> moduleDependencies = moduleDependenciesBuilder.build();
+        moduleElements.add(moduleElement);
+        for (TypeElement dependencyType : moduleDependencies) {
+          if (!moduleElements.contains(dependencyType)) {
+            moduleQueue.add(dependencyType);
+          }
+        }
+      }
+    }
+    return ImmutableSet.copyOf(moduleElements);
+  }
+
+  /** Returns the enclosed elements annotated with the given annotation type. */
+  static ImmutableList<DeclaredType> enclosedBuilders(TypeElement typeElement,
+      final Class<? extends Annotation> annotation) {
+    final ImmutableList.Builder<DeclaredType> builders = ImmutableList.builder();
+    for (TypeElement element : ElementFilter.typesIn(typeElement.getEnclosedElements())) {
+      if (MoreElements.isAnnotationPresent(element, annotation)) {
+        builders.add(MoreTypes.asDeclared(element.asType()));
+      }
+    }
+    return builders.build();
+  }
+
+  static boolean isSubcomponentType(TypeMirror type) {
+    return type.accept(new SubcomponentDetector(), null).isPresent();
+  }
+
+  private static final class SubcomponentDetector
+      extends SimpleTypeVisitor6<Optional<AnnotationMirror>, Void> {
+    @Override
+    protected Optional<AnnotationMirror> defaultAction(TypeMirror e, Void p) {
+      return Optional.absent();
+    }
+
+    @Override
+    public Optional<AnnotationMirror> visitDeclared(DeclaredType t, Void p) {
+      return MoreElements.getAnnotationMirror(t.asElement(), Subcomponent.class);
+    }
+  }
+
+  /** Traverses includes from superclasses and adds them into the builder. */
+  private static void addIncludesFromSuperclasses(Types types, TypeElement element,
+      ImmutableSet.Builder<TypeElement> builder, TypeMirror objectType) {
+    // Also add the superclass to the queue, in case any @Module definitions were on that.
+    TypeMirror superclass = element.getSuperclass();
+    while (!types.isSameType(objectType, superclass)
+        && superclass.getKind().equals(TypeKind.DECLARED)) {
+      element = MoreElements.asType(types.asElement(superclass));
+      Optional<AnnotationMirror> moduleMirror = getAnnotationMirror(element, Module.class)
+          .or(getAnnotationMirror(element, ProducerModule.class));
+      if (moduleMirror.isPresent()) {
+        builder.addAll(MoreTypes.asTypeElements(getModuleIncludes(moduleMirror.get())));
+      }
+      superclass = element.getSuperclass();
+    }
+  }
+
+  private ConfigurationAnnotations() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java b/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java
new file mode 100644
index 0000000..831943f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Component;
+import dagger.MapKey;
+import dagger.Provides;
+import dagger.producers.Produces;
+import dagger.producers.ProductionComponent;
+import java.util.EnumSet;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static dagger.internal.codegen.MapKeys.getMapKey;
+import static dagger.internal.codegen.MapKeys.unwrapValue;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * An abstract class for a value object representing the mechanism by which a {@link Key} can be
+ * contributed to a dependency graph.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+abstract class ContributionBinding extends Binding {
+  
+  @Override
+  Set<DependencyRequest> implicitDependencies() {
+    // Optimization: If we don't need the memberInjectionRequest, don't create more objects.
+    if (!membersInjectionRequest().isPresent()) {
+      return dependencies();
+    } else {
+      // Optimization: Avoid creating an ImmutableSet+Builder just to union two things together.
+      return Sets.union(membersInjectionRequest().asSet(), dependencies());
+    }
+  }
+
+  static enum ContributionType {
+    /** Represents map bindings. */
+    MAP,
+    /** Represents set bindings. */
+    SET,
+    /** Represents a valid non-collection binding. */
+    UNIQUE;
+
+    boolean isMultibinding() {
+      return !this.equals(UNIQUE);
+    }
+  }
+
+  ContributionType contributionType() {
+    switch (provisionType()) {
+      case SET:
+      case SET_VALUES:
+        return ContributionType.SET;
+      case MAP:
+        return ContributionType.MAP;
+      case UNIQUE:
+        return ContributionType.UNIQUE;
+      default:
+        throw new AssertionError("Unknown provision type: " + provisionType());
+    }
+  }
+  
+  /** Returns the type that specifies this' nullability, absent if not nullable. */
+  abstract Optional<DeclaredType> nullableType();
+
+  /**
+   * If this is a provision request from an {@code @Provides} or {@code @Produces} method, this will
+   * be the element that contributed it. In the case of subclassed modules, this may differ than the
+   * binding's enclosed element, as this will return the subclass whereas the enclosed element will
+   * be the superclass.
+   */
+  abstract Optional<TypeElement> contributedBy();
+
+  /**
+   * Returns whether this binding is synthetic, i.e., not explicitly tied to code, but generated
+   * implicitly by the framework.
+   */
+  boolean isSyntheticBinding() {
+    return bindingKind().equals(Kind.SYNTHETIC);
+  }
+
+  /** If this provision requires members injection, this will be the corresponding request. */
+  abstract Optional<DependencyRequest> membersInjectionRequest();
+
+  /**
+   * The kind of contribution this binding represents. Defines which elements can specify this kind
+   * of contribution.
+   */
+  enum Kind {
+    /**
+     * A binding that is not explicitly tied to an element, but generated implicitly by the
+     * framework.
+     */
+    SYNTHETIC,
+
+    // Provision kinds
+
+    /** An {@link Inject}-annotated constructor. */
+    INJECTION,
+
+    /** A {@link Provides}-annotated method. */
+    PROVISION,
+
+    /** An implicit binding to a {@link Component @Component}-annotated type. */
+    COMPONENT,
+
+    /** A provision method on a component's {@linkplain Component#dependencies() dependency}. */
+    COMPONENT_PROVISION,
+
+    /**
+     * A subcomponent builder method on a component or subcomponent.
+     */
+    SUBCOMPONENT_BUILDER,
+
+    // Production kinds
+
+    /** A {@link Produces}-annotated method that doesn't return a {@link ListenableFuture}. */
+    IMMEDIATE,
+
+    /** A {@link Produces}-annotated method that returns a {@link ListenableFuture}. */
+    FUTURE_PRODUCTION,
+
+    /**
+     * A production method on a production component's
+     * {@linkplain ProductionComponent#dependencies() dependency} that returns a
+     * {@link ListenableFuture}. Methods on production component dependencies that don't return a
+     * {@link ListenableFuture} are considered {@linkplain #PROVISION provision bindings}.
+     */
+    COMPONENT_PRODUCTION,
+  }
+
+  /**
+   * The kind of this contribution binding.
+   */
+  protected abstract Kind bindingKind();
+  
+  /**
+   * A predicate that passes for bindings of a given kind.
+   */
+  static Predicate<ContributionBinding> isOfKind(final Kind kind) {
+    return new Predicate<ContributionBinding>() {
+      @Override
+      public boolean apply(ContributionBinding binding) {
+        return binding.bindingKind().equals(kind);
+      }};
+  }
+
+  /** The provision type that was used to bind the key. */
+  abstract Provides.Type provisionType();
+
+  /**
+   * The strategy for getting an instance of a factory for a {@link ContributionBinding}.
+   */
+  enum FactoryCreationStrategy {
+    /** The factory class is an enum with one value named {@code INSTANCE}. */
+    ENUM_INSTANCE,
+    /** The factory must be created by calling the constructor. */
+    CLASS_CONSTRUCTOR,
+  }
+
+  /**
+   * Returns {@link FactoryCreationStrategy#ENUM_INSTANCE} if the binding has no dependencies and
+   * is a static provision binding or an {@link Inject @Inject} constructor binding. Otherwise
+   * returns {@link FactoryCreationStrategy#CLASS_CONSTRUCTOR}.
+   */
+  FactoryCreationStrategy factoryCreationStrategy() {
+    switch (bindingKind()) {
+      case PROVISION:
+        return implicitDependencies().isEmpty() && bindingElement().getModifiers().contains(STATIC)
+            ? FactoryCreationStrategy.ENUM_INSTANCE
+            : FactoryCreationStrategy.CLASS_CONSTRUCTOR;
+
+      case INJECTION:
+        return implicitDependencies().isEmpty()
+            ? FactoryCreationStrategy.ENUM_INSTANCE
+            : FactoryCreationStrategy.CLASS_CONSTRUCTOR;
+
+      default:
+        return FactoryCreationStrategy.CLASS_CONSTRUCTOR;
+    }
+  }
+
+  /**
+   * Returns the {@link ContributionType}s represented by a given {@link ContributionBinding}
+   * collection.
+   */
+  static <B extends ContributionBinding>
+      ImmutableListMultimap<ContributionType, B> contributionTypesFor(
+          Iterable<? extends B> bindings) {
+    ImmutableListMultimap.Builder<ContributionType, B> builder = ImmutableListMultimap.builder();
+    builder.orderKeysBy(Ordering.<ContributionType>natural());
+    for (B binding : bindings) {
+      builder.put(binding.contributionType(), binding);
+    }
+    return builder.build();
+  }
+
+  /**
+   * Returns a single {@link ContributionType} represented by a given collection of
+   * {@link ContributionBinding}s.
+   *
+   * @throws IllegalArgumentException if the given bindings are not all of one type
+   */
+  static ContributionType contributionTypeFor(Iterable<ContributionBinding> bindings) {
+    checkNotNull(bindings);
+    checkArgument(!Iterables.isEmpty(bindings), "no bindings");
+    Set<ContributionType> types = EnumSet.noneOf(ContributionType.class);
+    for (ContributionBinding binding : bindings) {
+      types.add(binding.contributionType());
+    }
+    if (types.size() > 1) {
+      throw new IllegalArgumentException(
+          String.format(ErrorMessages.MULTIPLE_CONTRIBUTION_TYPES_FORMAT, types));
+    }
+    return Iterables.getOnlyElement(types);
+  }
+
+  /**
+   * Indexes map-multibindings by map key (the result of calling
+   * {@link AnnotationValue#getValue()} on a single member or the whole {@link AnnotationMirror}
+   * itself, depending on {@link MapKey#unwrapValue()}).
+   */
+  static ImmutableSetMultimap<Object, ContributionBinding> indexMapBindingsByMapKey(
+      Set<ContributionBinding> mapBindings) {
+    return ImmutableSetMultimap.copyOf(
+        Multimaps.index(
+            mapBindings,
+            new Function<ContributionBinding, Object>() {
+              @Override
+              public Object apply(ContributionBinding mapBinding) {
+                AnnotationMirror mapKey = getMapKey(mapBinding.bindingElement()).get();
+                Optional<? extends AnnotationValue> unwrappedValue = unwrapValue(mapKey);
+                return unwrappedValue.isPresent() ? unwrappedValue.get().getValue() : mapKey;
+              }
+            }));
+  }
+
+  /**
+   * Indexes map-multibindings by map key annotation type.
+   */
+  static ImmutableSetMultimap<Wrapper<DeclaredType>, ContributionBinding>
+      indexMapBindingsByAnnotationType(Set<ContributionBinding> mapBindings) {
+    return ImmutableSetMultimap.copyOf(
+        Multimaps.index(
+            mapBindings,
+            new Function<ContributionBinding, Equivalence.Wrapper<DeclaredType>>() {
+              @Override
+              public Equivalence.Wrapper<DeclaredType> apply(ContributionBinding mapBinding) {
+                return MoreTypes.equivalence()
+                    .wrap(getMapKey(mapBinding.bindingElement()).get().getAnnotationType());
+              }
+            }));
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ContributionBindingFormatter.java b/compiler/src/main/java/dagger/internal/codegen/ContributionBindingFormatter.java
new file mode 100644
index 0000000..0d26761
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ContributionBindingFormatter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Optional;
+
+import static com.google.auto.common.MoreElements.asExecutable;
+import static com.google.auto.common.MoreTypes.asDeclared;
+
+/**
+ * Formats a {@link ContributionBinding} into a {@link String} suitable for use in error messages.
+ *
+ * @author Christian Gruber
+ * @since 2.0
+ */
+final class ContributionBindingFormatter extends Formatter<ContributionBinding> {
+  private final MethodSignatureFormatter methodSignatureFormatter;
+  
+  ContributionBindingFormatter(MethodSignatureFormatter methodSignatureFormatter) { 
+    this.methodSignatureFormatter = methodSignatureFormatter;
+  }
+
+  @Override public String format(ContributionBinding binding) {
+    switch (binding.bindingKind()) {
+      case COMPONENT_PROVISION:
+      case COMPONENT_PRODUCTION:
+        return methodSignatureFormatter.format(asExecutable(binding.bindingElement()));
+
+      case PROVISION:
+      case SUBCOMPONENT_BUILDER:
+      case IMMEDIATE:
+      case FUTURE_PRODUCTION:
+        return methodSignatureFormatter.format(
+            asExecutable(binding.bindingElement()),
+            Optional.of(asDeclared(binding.contributedBy().get().asType())));
+
+      default:
+        throw new UnsupportedOperationException(
+            "Not yet supporting " + binding.bindingKind() + " binding types.");
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/DependencyRequest.java b/compiler/src/main/java/dagger/internal/codegen/DependencyRequest.java
new file mode 100644
index 0000000..49fcd9c
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/DependencyRequest.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Lazy;
+import dagger.MembersInjector;
+import dagger.Provides;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.internal.AbstractProducer;
+import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+
+import static com.google.auto.common.MoreTypes.isTypeOf;
+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 javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.util.ElementFilter.constructorsIn;
+
+/**
+ * Represents a request for a key at an injection point. Parameters to {@link Inject} constructors
+ * or {@link Provides} methods are examples of key requests.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+// TODO(gak): Set bindings and the permutations thereof need to be addressed
+@AutoValue
+abstract class DependencyRequest {
+  static final Function<DependencyRequest, BindingKey> BINDING_KEY_FUNCTION =
+      new Function<DependencyRequest, BindingKey>() {
+        @Override public BindingKey apply(DependencyRequest request) {
+          return request.bindingKey();
+        }
+      };
+
+  enum Kind {
+    /** A default request for an instance.  E.g.: {@code Blah} */
+    INSTANCE,
+    /** A request for a {@link Provider}.  E.g.: {@code Provider<Blah>} */
+    PROVIDER,
+    /** A request for a {@link Lazy}.  E.g.: {@code Lazy<Blah>} */
+    LAZY,
+    /** A request for a {@link MembersInjector}.  E.g.: {@code MembersInjector<Blah>} */
+    MEMBERS_INJECTOR,
+    /** A request for a {@link Producer}.  E.g.: {@code Producer<Blah>} */
+    PRODUCER,
+    /** A request for a {@link Produced}.  E.g.: {@code Produced<Blah>} */
+    PRODUCED,
+    /**
+     * A request for a {@link ListenableFuture}.  E.g.: {@code ListenableFuture<Blah>}.
+     * These can only be requested by component interfaces.
+     */
+    FUTURE,
+  }
+
+  abstract Kind kind();
+  abstract Key key();
+
+  BindingKey bindingKey() {
+    switch (kind()) {
+      case INSTANCE:
+      case LAZY:
+      case PROVIDER:
+      case PRODUCER:
+      case PRODUCED:
+      case FUTURE:
+        return BindingKey.create(BindingKey.Kind.CONTRIBUTION, key());
+      case MEMBERS_INJECTOR:
+        return BindingKey.create(BindingKey.Kind.MEMBERS_INJECTION, key());
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  abstract Element requestElement();
+
+  /**
+   * Returns the possibly resolved type that contained the requesting element. For members injection
+   * requests, this is the type itself.
+   */
+  abstract DeclaredType enclosingType();
+
+  /** Returns true if this request allows null objects. */
+  abstract boolean isNullable();
+
+  /**
+   * An optional name for this request when it's referred to in generated code. If absent, it will
+   * use a name derived from {@link #requestElement}.
+   */
+  abstract Optional<String> overriddenVariableName();
+
+  /**
+   * Factory for {@link DependencyRequest}s.
+   *
+   * <p>Any factory method may throw {@link TypeNotPresentException} if a type is not available,
+   * which may mean that the type will be generated in a later round of processing.
+   */
+  static final class Factory {
+    private final Elements elements;
+    private final Key.Factory keyFactory;
+
+    Factory(Elements elements, Key.Factory keyFactory) {
+      this.elements = elements;
+      this.keyFactory = keyFactory;
+    }
+
+    ImmutableSet<DependencyRequest> forRequiredResolvedVariables(DeclaredType container,
+        List<? extends VariableElement> variables, List<? extends TypeMirror> resolvedTypes) {
+      checkState(resolvedTypes.size() == variables.size());
+      ImmutableSet.Builder<DependencyRequest> builder = ImmutableSet.builder();
+      for (int i = 0; i < variables.size(); i++) {
+        builder.add(forRequiredResolvedVariable(container, variables.get(i), resolvedTypes.get(i)));
+      }
+      return builder.build();
+    }
+
+    ImmutableSet<DependencyRequest> forRequiredVariables(
+        List<? extends VariableElement> variables) {
+      return FluentIterable.from(variables)
+          .transform(
+              new Function<VariableElement, DependencyRequest>() {
+                @Override
+                public DependencyRequest apply(VariableElement input) {
+                  return forRequiredVariable(input);
+                }
+              })
+          .toSet();
+    }
+
+    /**
+     * Creates a implicit {@link DependencyRequest} for {@code mapOfFactoryKey}, which will be used
+     * to satisfy the {@code mapOfValueRequest}.
+     * 
+     * @param mapOfValueRequest a request for {@code Map<K, V>}
+     * @param mapOfFactoryKey a key equivalent to {@code mapOfValueRequest}'s key, whose type is
+     *     {@code Map<K, Provider<V>>} or {@code Map<K, Producer<V>>}
+     */
+    DependencyRequest forImplicitMapBinding(
+        DependencyRequest mapOfValueRequest, Key mapOfFactoryKey) {
+      checkNotNull(mapOfValueRequest);
+      return new AutoValue_DependencyRequest(
+          Kind.PROVIDER,
+          mapOfFactoryKey,
+          mapOfValueRequest.requestElement(),
+          mapOfValueRequest.enclosingType(),
+          false /* doesn't allow null */,
+          Optional.<String>absent());
+    }
+
+    DependencyRequest forRequiredVariable(VariableElement variableElement) {
+      return forRequiredVariable(variableElement, Optional.<String>absent());
+    }
+
+    DependencyRequest forRequiredVariable(VariableElement variableElement, Optional<String> name) {
+      checkNotNull(variableElement);
+      TypeMirror type = variableElement.asType();
+      Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(variableElement);
+      return newDependencyRequest(
+          variableElement, type, qualifier, getEnclosingType(variableElement), name);
+    }
+
+    DependencyRequest forRequiredResolvedVariable(DeclaredType container,
+        VariableElement variableElement,
+        TypeMirror resolvedType) {
+      checkNotNull(variableElement);
+      checkNotNull(resolvedType);
+      Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(variableElement);
+      return newDependencyRequest(
+          variableElement, resolvedType, qualifier, container, Optional.<String>absent());
+    }
+
+    DependencyRequest forComponentProvisionMethod(ExecutableElement provisionMethod,
+        ExecutableType provisionMethodType) {
+      checkNotNull(provisionMethod);
+      checkNotNull(provisionMethodType);
+      checkArgument(
+          provisionMethod.getParameters().isEmpty(),
+          "Component provision methods must be empty: %s",
+          provisionMethod);
+      Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(provisionMethod);
+      return newDependencyRequest(
+          provisionMethod,
+          provisionMethodType.getReturnType(),
+          qualifier,
+          getEnclosingType(provisionMethod),
+          Optional.<String>absent());
+    }
+
+    DependencyRequest forComponentProductionMethod(ExecutableElement productionMethod,
+        ExecutableType productionMethodType) {
+      checkNotNull(productionMethod);
+      checkNotNull(productionMethodType);
+      checkArgument(productionMethod.getParameters().isEmpty(),
+          "Component production methods must be empty: %s", productionMethod);
+      TypeMirror type = productionMethodType.getReturnType();
+      Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(productionMethod);
+      DeclaredType container = getEnclosingType(productionMethod);
+      // Only a component production method can be a request for a ListenableFuture, so we
+      // special-case it here.
+      if (isTypeOf(ListenableFuture.class, type)) {
+        return new AutoValue_DependencyRequest(
+            Kind.FUTURE,
+            keyFactory.forQualifiedType(
+                qualifier, Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments())),
+            productionMethod,
+            container,
+            false /* doesn't allow null */,
+            Optional.<String>absent());
+      } else {
+        return newDependencyRequest(
+            productionMethod, type, qualifier, container, Optional.<String>absent());
+      }
+    }
+
+    DependencyRequest forComponentMembersInjectionMethod(ExecutableElement membersInjectionMethod,
+        ExecutableType membersInjectionMethodType) {
+      checkNotNull(membersInjectionMethod);
+      checkNotNull(membersInjectionMethodType);
+      Optional<AnnotationMirror> qualifier =
+          InjectionAnnotations.getQualifier(membersInjectionMethod);
+      checkArgument(!qualifier.isPresent());
+      TypeMirror returnType = membersInjectionMethodType.getReturnType();
+      if (returnType.getKind().equals(DECLARED)
+          && MoreTypes.isTypeOf(MembersInjector.class, returnType)) {
+        return new AutoValue_DependencyRequest(
+            Kind.MEMBERS_INJECTOR,
+            keyFactory.forMembersInjectedType(
+                Iterables.getOnlyElement(((DeclaredType) returnType).getTypeArguments())),
+            membersInjectionMethod,
+            getEnclosingType(membersInjectionMethod),
+            false /* doesn't allow null */,
+            Optional.<String>absent());
+      } else {
+        return new AutoValue_DependencyRequest(
+            Kind.MEMBERS_INJECTOR,
+            keyFactory.forMembersInjectedType(
+                Iterables.getOnlyElement(membersInjectionMethodType.getParameterTypes())),
+            membersInjectionMethod,
+            getEnclosingType(membersInjectionMethod),
+            false /* doesn't allow null */,
+            Optional.<String>absent());
+      }
+    }
+
+    DependencyRequest forMembersInjectedType(DeclaredType type) {
+      return new AutoValue_DependencyRequest(
+          Kind.MEMBERS_INJECTOR,
+          keyFactory.forMembersInjectedType(type),
+          type.asElement(),
+          type,
+          false /* doesn't allow null */,
+          Optional.<String>absent());
+    }
+
+    DependencyRequest forProductionComponentMonitorProvider() {
+      TypeElement element = elements.getTypeElement(AbstractProducer.class.getCanonicalName());
+      for (ExecutableElement constructor : constructorsIn(element.getEnclosedElements())) {
+        if (constructor.getParameters().size() == 2) {
+          // the 2-arg constructor has the appropriate dependency as its first arg
+          return forRequiredVariable(constructor.getParameters().get(0), Optional.of("monitor"));
+        }
+      }
+      throw new AssertionError("expected 2-arg constructor in AbstractProducer");
+    }
+
+    private DependencyRequest newDependencyRequest(
+        Element requestElement,
+        TypeMirror type,
+        Optional<AnnotationMirror> qualifier,
+        DeclaredType container,
+        Optional<String> name) {
+      KindAndType kindAndType = extractKindAndType(type);
+      if (kindAndType.kind().equals(Kind.MEMBERS_INJECTOR)) {
+        checkArgument(!qualifier.isPresent());
+      }
+      // Only instance types can be non-null -- all other requests are wrapped
+      // inside something (e.g, Provider, Lazy, etc..).
+      // TODO(sameb): should Produced/Producer always require non-nullable?
+      boolean allowsNull = !kindAndType.kind().equals(Kind.INSTANCE)
+          || ConfigurationAnnotations.getNullableType(requestElement).isPresent();
+      return new AutoValue_DependencyRequest(
+          kindAndType.kind(),
+          keyFactory.forQualifiedType(qualifier, kindAndType.type()),
+          requestElement,
+          container,
+          allowsNull,
+          name);
+    }
+
+    @AutoValue
+    static abstract class KindAndType {
+      abstract Kind kind();
+      abstract TypeMirror type();
+    }
+
+    /**
+     * Extracts the correct requesting type & kind out a request type. For example, if a user
+     * requests {@code Provider<Foo>}, this will return ({@link Kind#PROVIDER}, {@code Foo}).
+     *
+     * @throws TypeNotPresentException if {@code type}'s kind is {@link TypeKind#ERROR}, which may
+     *     mean that the type will be generated in a later round of processing
+     */
+    static KindAndType extractKindAndType(TypeMirror type) {
+      if (type.getKind().equals(TypeKind.ERROR)) {
+        throw new TypeNotPresentException(type.toString(), null);
+      }
+
+      // We must check TYPEVAR explicitly before the below checks because calling
+      // isTypeOf(..) on a TYPEVAR throws an exception (because it can't be
+      // represented as a Class).
+      if (type.getKind().equals(TypeKind.TYPEVAR)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.INSTANCE, type);
+      } else if (isTypeOf(Provider.class, type)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.PROVIDER,
+            Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments()));
+      } else if (isTypeOf(Lazy.class, type)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.LAZY,
+            Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments()));
+      } else if (isTypeOf(MembersInjector.class, type)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.MEMBERS_INJECTOR,
+            Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments()));
+      } else if (isTypeOf(Producer.class, type)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.PRODUCER,
+            Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments()));
+      } else if (isTypeOf(Produced.class, type)) {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.PRODUCED,
+            Iterables.getOnlyElement(((DeclaredType) type).getTypeArguments()));
+      } else {
+        return new AutoValue_DependencyRequest_Factory_KindAndType(Kind.INSTANCE, type);
+      }
+    }
+
+    static DeclaredType getEnclosingType(Element element) {
+      while (!MoreElements.isType(element)) {
+        element = element.getEnclosingElement();
+      }
+      return MoreTypes.asDeclared(element.asType());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/DependencyRequestFormatter.java b/compiler/src/main/java/dagger/internal/codegen/DependencyRequestFormatter.java
new file mode 100644
index 0000000..0e5f1f2
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/DependencyRequestFormatter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Optional;
+import java.util.List;
+import javax.lang.model.element.AnnotationMirror;
+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.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleElementVisitor6;
+import javax.lang.model.util.Types;
+
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static dagger.internal.codegen.ErrorMessages.INDENT;
+
+/**
+ * Formats a {@link DependencyRequest} into a {@link String} suitable for an error message listing
+ * a chain of dependencies.
+ *
+ * @author Christian Gruber
+ * @since 2.0
+ */
+final class DependencyRequestFormatter extends Formatter<DependencyRequest> {
+  private final Types types;
+
+  DependencyRequestFormatter(Types types) {
+    this.types = types;
+  }
+
+  // TODO(cgruber): Sweep this class for TypeMirror.toString() usage and do some preventive format.
+  // TODO(cgruber): consider returning a small structure containing strings to be indented later.
+  @Override public String format(final DependencyRequest request) {
+    Element requestElement = request.requestElement();
+    Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(requestElement);
+    return requestElement.accept(new SimpleElementVisitor6<String, Optional<AnnotationMirror>>(){
+
+      /* Handle component methods */
+      @Override public String visitExecutable(
+          ExecutableElement method, Optional<AnnotationMirror> qualifier) {
+        StringBuilder builder = new StringBuilder(INDENT);
+        if (method.getParameters().isEmpty()) {
+          // some.package.name.MyComponent.myMethod()
+          //     [component method with return type: @other.package.Qualifier some.package.name.Foo]
+          appendEnclosingTypeAndMemberName(method, builder).append("()\n")
+              .append(INDENT).append(INDENT).append("[component method with return type: ");
+          if (qualifier.isPresent()) {
+            // TODO(cgruber) use chenying's annotation mirror stringifier
+            builder.append(qualifier.get()).append(' ');
+          }
+          builder.append(method.getReturnType()).append(']');
+        } else {
+          // some.package.name.MyComponent.myMethod(some.package.name.Foo foo)
+          //     [component injection method for type: some.package.name.Foo]
+          VariableElement componentMethodParameter = getOnlyElement(method.getParameters());
+          appendEnclosingTypeAndMemberName(method, builder).append("(");
+          appendParameter(componentMethodParameter, componentMethodParameter.asType(), builder);
+          builder.append(")\n");
+          builder.append(INDENT).append(INDENT).append("[component injection method for type: ")
+              .append(componentMethodParameter.asType())
+              .append(']');
+        }
+        return builder.toString();
+      }
+
+      /* Handle injected fields or method/constructor parameter injection. */
+      @Override public String visitVariable(
+          VariableElement variable, Optional<AnnotationMirror> qualifier) {
+        StringBuilder builder = new StringBuilder(INDENT);
+        TypeMirror resolvedVariableType =
+            MoreTypes.asMemberOf(types, request.enclosingType(), variable);
+        if (variable.getKind().equals(ElementKind.PARAMETER)) {
+          // some.package.name.MyClass.myMethod(some.package.name.Foo arg0, some.package.Bar arg1)
+          //     [parameter: @other.package.Qualifier some.package.name.Foo arg0]
+          ExecutableElement methodOrConstructor =
+              MoreElements.asExecutable(variable.getEnclosingElement());
+          ExecutableType resolvedMethodOrConstructor = MoreTypes.asExecutable(
+              types.asMemberOf(request.enclosingType(), methodOrConstructor));
+          appendEnclosingTypeAndMemberName(methodOrConstructor, builder).append('(');
+          List<? extends VariableElement> parameters = methodOrConstructor.getParameters();
+          List<? extends TypeMirror> parameterTypes =
+              resolvedMethodOrConstructor.getParameterTypes();
+          checkState(parameters.size() == parameterTypes.size());
+          for (int i = 0; i < parameters.size(); i++) {
+            appendParameter(parameters.get(i), parameterTypes.get(i), builder);
+            if (i != parameters.size() - 1) {
+              builder.append(", ");
+            }
+          }
+          builder.append(")\n").append(INDENT).append(INDENT).append("[parameter: ");
+        } else {
+          // some.package.name.MyClass.myField
+          //     [injected field of type: @other.package.Qualifier some.package.name.Foo myField]
+          appendEnclosingTypeAndMemberName(variable, builder).append("\n")
+              .append(INDENT).append(INDENT).append("[injected field of type: ");
+        }
+        if (qualifier.isPresent()) {
+          // TODO(cgruber) use chenying's annotation mirror stringifier
+          builder.append(qualifier.get()).append(' ');
+        }
+        builder.append(resolvedVariableType)
+            .append(' ')
+            .append(variable.getSimpleName())
+            .append(']');
+        return builder.toString();
+      }
+
+      @Override
+      public String visitType(TypeElement e, Optional<AnnotationMirror> p) {
+        return ""; // types by themselves provide no useful information.
+      }
+
+      @Override protected String defaultAction(Element element, Optional<AnnotationMirror> ignore) {
+        throw new IllegalStateException(
+            "Invalid request " + element.getKind() +  " element " + element);
+      }
+    }, qualifier);
+  }
+
+  private StringBuilder appendParameter(VariableElement parameter, TypeMirror type,
+      StringBuilder builder) {
+    return builder.append(type).append(' ').append(parameter.getSimpleName());
+  }
+
+  private StringBuilder appendEnclosingTypeAndMemberName(Element member, StringBuilder builder) {
+    TypeElement type = MoreElements.asType(member.getEnclosingElement());
+    return builder.append(type.getQualifiedName())
+        .append('.')
+        .append(member.getSimpleName());
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java b/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java
new file mode 100644
index 0000000..1dc48fc
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import dagger.MembersInjector;
+import dagger.producers.Producer;
+import javax.inject.Provider;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+/**
+ * A mapper for associating a {@link DependencyRequest} to a framework class, dependent on
+ * the type of code to be generated (e.g., for {@link Provider} or {@link Producer}).
+ *
+ *  @author Jesse Beder
+ *  @since 2.0
+ */
+abstract class DependencyRequestMapper {
+  abstract Class<?> getFrameworkClass(DependencyRequest request);
+
+  /**
+   * Returns the framework class to use for a collection of requests of the same {@link BindingKey}.
+   * This allows factories to only take a single argument for multiple requests of the same key.
+   */
+  Class<?> getFrameworkClass(Iterable<DependencyRequest> requests) {
+    ImmutableSet<Class<?>> classes = FluentIterable.from(requests)
+        .transform(new Function<DependencyRequest, Class<?>>() {
+          @Override public Class<?> apply(DependencyRequest request) {
+            return getFrameworkClass(request);
+          }
+        })
+        .toSet();
+    if (classes.size() == 1) {
+      return getOnlyElement(classes);
+    } else if (classes.equals(ImmutableSet.of(Producer.class, Provider.class))) {
+      return Provider.class;
+    } else {
+      throw new IllegalStateException("Bad set of framework classes: " + classes);
+    }
+  }
+
+  private static final class MapperForProvider extends DependencyRequestMapper {
+    @Override public Class<?> getFrameworkClass(DependencyRequest request) {
+      switch (request.kind()) {
+        case INSTANCE:
+        case PROVIDER:
+        case LAZY:
+          return Provider.class;
+        case MEMBERS_INJECTOR:
+          return MembersInjector.class;
+        case PRODUCED:
+        case PRODUCER:
+          throw new IllegalArgumentException();
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  static final DependencyRequestMapper FOR_PROVIDER = new MapperForProvider();
+
+  private static final class MapperForProducer extends DependencyRequestMapper {
+    @Override public Class<?> getFrameworkClass(DependencyRequest request) {
+      switch (request.kind()) {
+        case INSTANCE:
+        case PRODUCED:
+        case PRODUCER:
+          return Producer.class;
+        case PROVIDER:
+        case LAZY:
+          return Provider.class;
+        case MEMBERS_INJECTOR:
+          return MembersInjector.class;
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  static final DependencyRequestMapper FOR_PRODUCER = new MapperForProducer();
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/DependencyVariableNamer.java b/compiler/src/main/java/dagger/internal/codegen/DependencyVariableNamer.java
new file mode 100644
index 0000000..5ba5635
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/DependencyVariableNamer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Ascii;
+import com.google.common.base.Function;
+import dagger.Lazy;
+import javax.inject.Provider;
+
+/**
+ * Picks a reasonable name for what we think is being provided from the variable name associated
+ * with the {@link DependencyRequest}.  I.e. strips out words like "lazy" and "provider" if we
+ * believe that those refer to {@link Lazy} and {@link Provider} rather than the type being
+ * provided.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+//TODO(gak): develop the heuristics to get better names
+final class DependencyVariableNamer implements Function<DependencyRequest, String> {
+  @Override
+  public String apply(DependencyRequest dependency) {
+    if (dependency.overriddenVariableName().isPresent()) {
+      return dependency.overriddenVariableName().get();
+    }
+    String variableName = dependency.requestElement().getSimpleName().toString();
+    switch (dependency.kind()) {
+      case INSTANCE:
+        return variableName;
+      case LAZY:
+        return variableName.startsWith("lazy") && !variableName.equals("lazy")
+            ? Ascii.toLowerCase(variableName.charAt(4)) + variableName.substring(5)
+            : variableName;
+      case PROVIDER:
+        return variableName.endsWith("Provider") && !variableName.equals("Provider")
+            ? variableName.substring(0, variableName.length() - 8)
+            : variableName;
+      case MEMBERS_INJECTOR:
+        return variableName.endsWith("MembersInjector") && !variableName.equals("MembersInjector")
+            ? variableName.substring(0, variableName.length() - 15)
+            : variableName;
+      case PRODUCED:
+        return variableName.startsWith("produced") && !variableName.equals("produced")
+            ? Ascii.toLowerCase(variableName.charAt(8)) + variableName.substring(9)
+            : variableName;
+      case PRODUCER:
+        return variableName.endsWith("Producer") && !variableName.equals("Producer")
+            ? variableName.substring(0, variableName.length() - 8)
+            : variableName;
+      default:
+        throw new AssertionError();
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ErrorMessages.java b/compiler/src/main/java/dagger/internal/codegen/ErrorMessages.java
new file mode 100644
index 0000000..1f52aca
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ErrorMessages.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 dagger.Provides;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.lang.model.element.AnnotationMirror;
+
+/**
+ * The collection of error messages to be reported back to users.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class ErrorMessages {
+  /*
+   * Common constants.
+   */
+  static final String INDENT = "    ";
+  static final int DUPLICATE_SIZE_LIMIT = 10;
+
+  /*
+   * JSR-330 errors
+   *
+   * These are errors that are explicitly outlined in the JSR-330 APIs
+   */
+
+  /* constructors */
+  static final String MULTIPLE_INJECT_CONSTRUCTORS =
+      "Types may only contain one @Inject constructor.";
+
+  /* fields */
+  static final String FINAL_INJECT_FIELD = "@Inject fields may not be final";
+
+  /* methods */
+  static final String ABSTRACT_INJECT_METHOD = "Methods with @Inject may not be abstract.";
+  static final String GENERIC_INJECT_METHOD =
+      "Methods with @Inject may not declare type parameters.";
+
+  /* qualifiers */
+  static final String MULTIPLE_QUALIFIERS =
+      "A single injection site may not use more than one @Qualifier.";
+
+  /* scope */
+  static final String MULTIPLE_SCOPES = "A single binding may not declare more than one @Scope.";
+
+  /*
+   * Dagger errors
+   *
+   * These are errors that arise due to restrictions imposed by the dagger implementation.
+   */
+
+  /* constructors */
+  static final String INJECT_ON_PRIVATE_CONSTRUCTOR =
+      "Dagger does not support injection into private constructors";
+  static final String INJECT_CONSTRUCTOR_ON_INNER_CLASS =
+      "@Inject constructors are invalid on inner classes";
+  static final String INJECT_CONSTRUCTOR_ON_ABSTRACT_CLASS =
+      "@Inject is nonsense on the constructor of an abstract class";
+    static final String QUALIFIER_ON_INJECT_CONSTRUCTOR =
+      "@Qualifier annotations are not allowed on @Inject constructors.";
+
+  /* fields */
+  static final String PRIVATE_INJECT_FIELD =
+      "Dagger does not support injection into private fields";
+  
+  static final String STATIC_INJECT_FIELD =
+      "Dagger does not support injection into static fields";
+
+  /* methods */
+  static final String PRIVATE_INJECT_METHOD =
+      "Dagger does not support injection into private methods";
+  
+  static final String STATIC_INJECT_METHOD =
+      "Dagger does not support injection into static methods";
+
+  /* all */
+  static final String INJECT_INTO_PRIVATE_CLASS =
+      "Dagger does not support injection into private classes";
+
+  /*
+   * Configuration errors
+   *
+   * These are errors that relate specifically to the Dagger configuration API (@Module, @Provides,
+   * etc.)
+   */
+  static final String DUPLICATE_BINDINGS_FOR_KEY_FORMAT =
+      "%s is bound multiple times:";
+
+  static String duplicateMapKeysError(String key) {
+    return "The same map key is bound more than once for " + key;
+  }
+
+  static String inconsistentMapKeyAnnotationsError(String key) {
+    return key + " uses more than one @MapKey annotation type";
+  }
+
+  static final String PROVIDES_METHOD_RETURN_TYPE =
+      "@Provides methods must either return a primitive, an array or a declared type.";
+
+  static final String PRODUCES_METHOD_RETURN_TYPE =
+      "@Produces methods must either return a primitive, an array or a declared type, or a"
+      + " ListenableFuture of one of those types.";
+
+  static final String PRODUCES_METHOD_RAW_FUTURE =
+      "@Produces methods cannot return a raw ListenableFuture.";
+
+  static final String BINDING_METHOD_SET_VALUES_RAW_SET =
+      "@%s methods of type set values cannot return a raw Set";
+
+  static final String PROVIDES_METHOD_SET_VALUES_RETURN_SET =
+      "@Provides methods of type set values must return a Set";
+
+  static final String PRODUCES_METHOD_SET_VALUES_RETURN_SET =
+      "@Produces methods of type set values must return a Set or ListenableFuture of Set";
+
+  static final String BINDING_METHOD_MUST_RETURN_A_VALUE =
+      "@%s methods must return a value (not void).";
+
+  static final String BINDING_METHOD_ABSTRACT = "@%s methods cannot be abstract";
+
+  static final String BINDING_METHOD_PRIVATE = "@%s methods cannot be private";
+
+  static final String BINDING_METHOD_TYPE_PARAMETER =
+      "@%s methods may not have type parameters.";
+
+  static final String BINDING_METHOD_NOT_IN_MODULE =
+      "@%s methods can only be present within a @%s";
+
+  static final String BINDING_METHOD_NOT_MAP_HAS_MAP_KEY =
+      "@%s methods of non map type cannot declare a map key";
+
+  static final String BINDING_METHOD_WITH_NO_MAP_KEY =
+      "@%s methods of type map must declare a map key";
+
+  static final String BINDING_METHOD_WITH_MULTIPLE_MAP_KEY =
+      "@%s methods may not have more than one @MapKey-marked annotation";
+
+  static final String BINDING_METHOD_WITH_SAME_NAME =
+      "Cannot have more than one @%s method with the same name in a single module";
+
+  static final String MODULES_WITH_TYPE_PARAMS_MUST_BE_ABSTRACT =
+      "Modules with type parameters must be abstract";
+
+  static final String REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT =
+      "%s is listed as a module, but is an abstract class or interface";
+
+  static final String REFERENCED_MODULE_NOT_ANNOTATED =
+      "%s is listed as a module, but is not annotated with %s";
+
+  static final String REFERENCED_MODULE_MUST_NOT_HAVE_TYPE_PARAMS =
+      "%s is listed as a module, but has type parameters";
+
+  static final String PROVIDES_METHOD_OVERRIDES_ANOTHER =
+      "@%s methods may not override another method. Overrides: %s";
+
+  static final String METHOD_OVERRIDES_PROVIDES_METHOD =
+      "@%s methods may not be overridden in modules. Overrides: %s";
+
+  static final String PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS =
+      "Cannot use more than one @Qualifier on a @Provides or @Produces method";
+
+  /* mapKey errors*/
+  static final String MAPKEY_WITHOUT_MEMBERS =
+      "Map key annotations must have members";
+
+  static final String UNWRAPPED_MAP_KEY_WITH_TOO_MANY_MEMBERS=
+      "Map key annotations with unwrapped values must have exactly one member";
+
+  static final String UNWRAPPED_MAP_KEY_WITH_ARRAY_MEMBER =
+      "Map key annotations with unwrapped values cannot use arrays";
+
+  /* collection binding errors */
+  static final String MULTIPLE_CONTRIBUTION_TYPES_FORMAT =
+      "More than one binding present of different types %s";
+
+  static final String MULTIPLE_BINDING_TYPES_FOR_KEY_FORMAT =
+      "%s has incompatible bindings:\n";
+
+  static final String PROVIDER_ENTRY_POINT_MAY_NOT_DEPEND_ON_PRODUCER_FORMAT =
+      "%s is a provision entry-point, which cannot depend on a production.";
+
+  static final String PROVIDER_MAY_NOT_DEPEND_ON_PRODUCER_FORMAT =
+      "%s is a provision, which cannot depend on a production.";
+
+  static final String REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_FORMAT =
+      "%s cannot be provided without an @Inject constructor or from an @Provides-annotated method.";
+
+  static final String REQUIRES_PROVIDER_FORMAT =
+      "%s cannot be provided without an @Provides-annotated method.";
+
+  static final String REQUIRES_AT_INJECT_CONSTRUCTOR_OR_PROVIDER_OR_PRODUCER_FORMAT =
+      "%s cannot be provided without an @Inject constructor or from an @Provides- or "
+      + "@Produces-annotated method.";
+
+  static final String REQUIRES_PROVIDER_OR_PRODUCER_FORMAT =
+      "%s cannot be provided without an @Provides- or @Produces-annotated method.";
+
+  static final String MEMBERS_INJECTION_DOES_NOT_IMPLY_PROVISION =
+      "This type supports members injection but cannot be implicitly provided.";
+
+  static final String MEMBERS_INJECTION_WITH_RAW_TYPE =
+      "%s has type parameters, cannot members inject the raw type. via:\n%s";
+
+  static final String MEMBERS_INJECTION_WITH_UNBOUNDED_TYPE =
+      "Type parameters must be bounded for members injection. %s required by %s, via:\n%s";
+
+  static final String CONTAINS_DEPENDENCY_CYCLE_FORMAT = "%s.%s() contains a dependency cycle:\n%s";
+
+  static final String MALFORMED_MODULE_METHOD_FORMAT =
+      "Cannot generated a graph because method %s on module %s was malformed";
+
+  static String nullableToNonNullable(String typeName, String bindingString) {
+    return String.format(
+            "%s is not nullable, but is being provided by %s",
+            typeName,
+            bindingString);
+  }
+
+  static final String CANNOT_RETURN_NULL_FROM_NON_NULLABLE_COMPONENT_METHOD =
+      "Cannot return null from a non-@Nullable component method";
+
+  static final String CANNOT_RETURN_NULL_FROM_NON_NULLABLE_PROVIDES_METHOD =
+      "Cannot return null from a non-@Nullable @Provides method";
+
+  static ComponentBuilderMessages builderMsgsFor(ComponentDescriptor.Kind kind) {
+    switch(kind) {
+      case COMPONENT:
+        return ComponentBuilderMessages.INSTANCE;
+      case SUBCOMPONENT:
+        return SubcomponentBuilderMessages.INSTANCE;
+      case PRODUCTION_COMPONENT:
+        return ProductionComponentBuilderMessages.INSTANCE;
+      default:
+        throw new IllegalStateException(kind.toString());
+    }
+  }
+
+  static class ComponentBuilderMessages {
+    static final ComponentBuilderMessages INSTANCE = new ComponentBuilderMessages();
+
+    protected String process(String s) { return s; }
+
+    /** Errors for component builders. */
+    final String moreThanOne() {
+      return process("@Component has more than one @Component.Builder: %s");
+    }
+
+    final String cxtorOnlyOneAndNoArgs() {
+      return process("@Component.Builder classes must have exactly one constructor,"
+          + " and it must not have any parameters");
+    }
+
+    final String generics() {
+      return process("@Component.Builder types must not have any generic types");
+    }
+
+    final String mustBeInComponent() {
+      return process("@Component.Builder types must be nested within a @Component");
+    }
+
+    final String mustBeClassOrInterface() {
+      return process("@Component.Builder types must be abstract classes or interfaces");
+    }
+
+    final String isPrivate() {
+      return process("@Component.Builder types must not be private");
+    }
+
+    final String mustBeStatic() {
+      return process("@Component.Builder types must be static");
+    }
+
+    final String mustBeAbstract() {
+      return process("@Component.Builder types must be abstract");
+    }
+
+    final String missingBuildMethod() {
+      return process("@Component.Builder types must have exactly one no-args method that "
+          + " returns the @Component type");
+    }
+
+    final String manyMethodsForType() {
+      return process("@Component.Builder types must not have more than one setter method per type,"
+          + " but %s is set by %s");
+    }
+
+    final String extraSetters() {
+      return process(
+          "@Component.Builder has setters for modules or components that aren't required: %s");
+    }
+
+    final String missingSetters() {
+      return process(
+          "@Component.Builder is missing setters for required modules or components: %s");
+    }
+
+    final String twoBuildMethods() {
+      return process("@Component.Builder types must have exactly one zero-arg method, and that"
+          + " method must return the @Component type. Already found: %s");
+    }
+
+    final String inheritedTwoBuildMethods() {
+      return process("@Component.Builder types must have exactly one zero-arg method, and that"
+          + " method must return the @Component type. Found %s and %s");
+    }
+
+    final String buildMustReturnComponentType() {
+      return process(
+          "@Component.Builder methods that have no arguments must return the @Component type");
+    }
+
+    final String inheritedBuildMustReturnComponentType() {
+      return process(
+          "@Component.Builder methods that have no arguments must return the @Component type"
+          + " Inherited method: %s");
+    }
+
+    final String methodsMustTakeOneArg() {
+      return process("@Component.Builder methods must not have more than one argument");
+    }
+
+    final String inheritedMethodsMustTakeOneArg() {
+      return process(
+          "@Component.Builder methods must not have more than one argument. Inherited method: %s");
+    }
+
+    final String methodsMustReturnVoidOrBuilder() {
+      return process("@Component.Builder setter methods must return void, the builder,"
+          + " or a supertype of the builder");
+    }
+
+    final String inheritedMethodsMustReturnVoidOrBuilder() {
+      return process("@Component.Builder setter methods must return void, the builder,"
+          + "or a supertype of the builder. Inherited method: %s");
+    }
+
+    final String methodsMayNotHaveTypeParameters() {
+      return process("@Component.Builder methods must not have type parameters");
+    }
+
+    final String inheritedMethodsMayNotHaveTypeParameters() {
+      return process(
+          "@Component.Builder methods must not have type parameters. Inherited method: %s");
+    }
+  }
+
+  static final class SubcomponentBuilderMessages extends ComponentBuilderMessages {
+    @SuppressWarnings("hiding")
+    static final SubcomponentBuilderMessages INSTANCE = new SubcomponentBuilderMessages();
+
+    @Override protected String process(String s) {
+      return s.replaceAll("component", "subcomponent").replaceAll("Component", "Subcomponent");
+    }
+
+    String builderMethodRequiresNoArgs() {
+      return "Methods returning a @Subcomponent.Builder must have no arguments";
+    }
+
+    String moreThanOneRefToSubcomponent() {
+      return "Only one method can create a given subcomponent. %s is created by: %s";
+    }
+  }
+
+  static final class ProductionComponentBuilderMessages extends ComponentBuilderMessages {
+    @SuppressWarnings("hiding")
+    static final ProductionComponentBuilderMessages INSTANCE =
+        new ProductionComponentBuilderMessages();
+
+    @Override protected String process(String s) {
+      return s.replaceAll("component", "production component")
+          .replaceAll("Component", "ProductionComponent");
+    }
+  }
+
+  /**
+   * A regular expression to match a small list of specific packages deemed to
+   * be unhelpful to display in fully qualified types in error messages.
+   *
+   * Note: This should never be applied to messages themselves.
+   */
+  private static final Pattern COMMON_PACKAGE_PATTERN = Pattern.compile(
+      "(?:^|[^.a-z_])"     // What we want to match on but not capture.
+      + "((?:"             // Start a group with a non-capturing or part
+      + "java[.]lang"
+      + "|java[.]util"
+      + "|javax[.]inject"
+      + "|dagger"
+      + "|com[.]google[.]common[.]base"
+      + "|com[.]google[.]common[.]collect"
+      + ")[.])"            // Always end with a literal .
+      + "[A-Z]");           // What we want to match on but not capture.
+
+  /**
+   * A method to strip out common packages and a few rare type prefixes
+   * from types' string representation before being used in error messages.
+   *
+   * This type assumes a String value that is a valid fully qualified
+   * (and possibly parameterized) type, and should NOT be used with
+   * arbitrary text, especially prose error messages.
+   *
+   * TODO(cgruber): Tighten these to take type representations (mirrors
+   *     and elements) to avoid accidental mis-use by running errors
+   *     through this method.
+   */
+  static String stripCommonTypePrefixes(String type) {
+    // Special case this enum's constants since they will be incredibly common.
+    type = type.replace(Provides.Type.class.getCanonicalName() + ".", "");
+
+    // Do regex magic to remove common packages we care to shorten.
+    Matcher matcher = COMMON_PACKAGE_PATTERN.matcher(type);
+    StringBuilder result = new StringBuilder();
+    int index = 0;
+    while (matcher.find()) {
+      result.append(type.subSequence(index, matcher.start(1)));
+      index = matcher.end(1); // Skip the matched pattern content.
+    }
+    result.append(type.subSequence(index, type.length()));
+    return result.toString();
+  }
+
+  //TODO(cgruber): Extract Formatter and do something less stringy.
+  static String format(AnnotationMirror annotation) {
+    return stripCommonTypePrefixes(annotation.toString());
+  }
+
+  private ErrorMessages() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/FactoryGenerator.java b/compiler/src/main/java/dagger/internal/codegen/FactoryGenerator.java
new file mode 100644
index 0000000..a0a48c8
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/FactoryGenerator.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import dagger.MembersInjector;
+import dagger.Provides.Type;
+import dagger.internal.Factory;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.ConstructorWriter;
+import dagger.internal.codegen.writer.EnumWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.StringLiteral;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import dagger.internal.codegen.writer.TypeVariableName;
+import dagger.internal.codegen.writer.TypeWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import javax.annotation.processing.Filer;
+import javax.inject.Inject;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
+
+import static com.google.common.base.Preconditions.checkState;
+import static dagger.Provides.Type.SET;
+import static dagger.internal.codegen.ContributionBinding.Kind.PROVISION;
+import static dagger.internal.codegen.ErrorMessages.CANNOT_RETURN_NULL_FROM_NON_NULLABLE_PROVIDES_METHOD;
+import static dagger.internal.codegen.SourceFiles.frameworkTypeUsageStatement;
+import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
+import static dagger.internal.codegen.SourceFiles.parameterizedGeneratedTypeNameForBinding;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+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;
+
+/**
+ * Generates {@link Factory} implementations from {@link ProvisionBinding} instances for
+ * {@link Inject} constructors.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding> {
+  private final DependencyRequestMapper dependencyRequestMapper;
+  private final Diagnostic.Kind nullableValidationType;
+
+  FactoryGenerator(Filer filer, DependencyRequestMapper dependencyRequestMapper,
+      Diagnostic.Kind nullableValidationType) {
+    super(filer);
+    this.dependencyRequestMapper = dependencyRequestMapper;
+    this.nullableValidationType = nullableValidationType;
+  }
+
+  @Override
+  ClassName nameGeneratedType(ProvisionBinding binding) {
+    return generatedClassNameForBinding(binding);
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(ProvisionBinding binding) {
+    return ImmutableSet.of(binding.bindingElement());
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(ProvisionBinding binding) {
+    return Optional.of(binding.bindingElement());
+  }
+
+  @Override
+  ImmutableSet<JavaWriter> write(ClassName generatedTypeName, ProvisionBinding binding) {
+    // We don't want to write out resolved bindings -- we want to write out the generic version.
+    checkState(!binding.hasNonDefaultTypeParameters());
+
+    TypeMirror keyType = binding.provisionType().equals(Type.MAP)
+        ? Util.getProvidedValueTypeOfMap(MoreTypes.asDeclared(binding.key().type()))
+        : binding.key().type();
+    TypeName providedTypeName = TypeNames.forTypeMirror(keyType);
+    JavaWriter writer = JavaWriter.inPackage(generatedTypeName.packageName());
+
+    final TypeWriter factoryWriter;
+    final Optional<ConstructorWriter> constructorWriter;
+    List<TypeVariableName> typeParameters = Lists.newArrayList();
+    for (TypeParameterElement typeParameter : binding.bindingTypeElement().getTypeParameters()) {
+     typeParameters.add(TypeVariableName.fromTypeParameterElement(typeParameter));
+    }
+    switch (binding.factoryCreationStrategy()) {
+      case ENUM_INSTANCE:
+        EnumWriter enumWriter = writer.addEnum(generatedTypeName.simpleName());
+        enumWriter.addConstant("INSTANCE");
+        constructorWriter = Optional.absent();
+        factoryWriter = enumWriter;
+        // If we have type parameters, then remove the parameters from our providedTypeName,
+        // since we'll be implementing an erased version of it.
+        if (!typeParameters.isEmpty()) {
+          factoryWriter.annotate(SuppressWarnings.class).setValue("rawtypes");
+          providedTypeName = ((ParameterizedTypeName) providedTypeName).type();
+        }
+        break;
+      case CLASS_CONSTRUCTOR:
+        ClassWriter classWriter = writer.addClass(generatedTypeName.simpleName());
+        classWriter.addTypeParameters(typeParameters);
+        classWriter.addModifiers(FINAL);
+        constructorWriter = Optional.of(classWriter.addConstructor());
+        constructorWriter.get().addModifiers(PUBLIC);
+        factoryWriter = classWriter;
+        if (binding.bindingKind().equals(PROVISION)
+            && !binding.bindingElement().getModifiers().contains(STATIC)) {
+          TypeName enclosingType = TypeNames.forTypeMirror(binding.bindingTypeElement().asType());
+          factoryWriter.addField(enclosingType, "module").addModifiers(PRIVATE, FINAL);
+          constructorWriter.get().addParameter(enclosingType, "module");
+          constructorWriter.get().body()
+              .addSnippet("assert module != null;")
+              .addSnippet("this.module = module;");
+        }
+        break;
+      default:
+        throw new AssertionError();
+    }
+
+    factoryWriter.annotate(Generated.class).setValue(ComponentProcessor.class.getName());
+    factoryWriter.addModifiers(PUBLIC);
+    factoryWriter.addImplementedType(
+        ParameterizedTypeName.create(ClassName.fromClass(Factory.class), providedTypeName));
+
+    MethodWriter getMethodWriter = factoryWriter.addMethod(providedTypeName, "get");
+    getMethodWriter.annotate(Override.class);
+    getMethodWriter.addModifiers(PUBLIC);
+
+    if (binding.membersInjectionRequest().isPresent()) {
+      ParameterizedTypeName membersInjectorType = ParameterizedTypeName.create(
+          MembersInjector.class, providedTypeName);
+      factoryWriter.addField(membersInjectorType, "membersInjector").addModifiers(PRIVATE, FINAL);
+      constructorWriter.get().addParameter(membersInjectorType, "membersInjector");
+      constructorWriter.get().body()
+          .addSnippet("assert membersInjector != null;")
+          .addSnippet("this.membersInjector = membersInjector;");
+    }
+
+    ImmutableMap<BindingKey, FrameworkField> fields =
+        SourceFiles.generateBindingFieldsForDependencies(
+            dependencyRequestMapper, binding.dependencies());
+
+    for (FrameworkField bindingField : fields.values()) {
+      TypeName fieldType = bindingField.frameworkType();
+      FieldWriter field = factoryWriter.addField(fieldType, bindingField.name());
+      field.addModifiers(PRIVATE, FINAL);
+      constructorWriter.get().addParameter(field.type(), field.name());
+      constructorWriter.get().body()
+          .addSnippet("assert %s != null;", field.name())
+          .addSnippet("this.%1$s = %1$s;", field.name());
+    }
+
+    // If constructing a factory for @Inject or @Provides bindings, we use a static create method
+    // so that generated components can avoid having to refer to the generic types
+    // of the factory.  (Otherwise they may have visibility problems referring to the types.)
+    switch(binding.bindingKind()) {
+      case INJECTION:
+      case PROVISION:
+        // The return type is usually the same as the implementing type, except in the case
+        // of enums with type variables (where we cast).
+        TypeName returnType = ParameterizedTypeName.create(ClassName.fromClass(Factory.class),
+            TypeNames.forTypeMirror(keyType));
+        MethodWriter createMethodWriter = factoryWriter.addMethod(returnType, "create");
+        createMethodWriter.addTypeParameters(typeParameters);
+        createMethodWriter.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+        Map<String, TypeName> params = constructorWriter.isPresent()
+            ? constructorWriter.get().parameters() : ImmutableMap.<String, TypeName>of();
+        for (Map.Entry<String, TypeName> param : params.entrySet()) {
+          createMethodWriter.addParameter(param.getValue(), param.getKey());
+        }
+        switch (binding.factoryCreationStrategy()) {
+          case ENUM_INSTANCE:
+            if (typeParameters.isEmpty()) {
+              createMethodWriter.body().addSnippet("return INSTANCE;");
+            } else {
+              // We use an unsafe cast here because the types are different.
+              // It's safe because the type is never referenced anywhere.
+              createMethodWriter.annotate(SuppressWarnings.class).setValue("unchecked");
+              createMethodWriter.body().addSnippet("return (Factory) INSTANCE;");
+            }
+            break;
+          case CLASS_CONSTRUCTOR:
+            createMethodWriter.body().addSnippet("return new %s(%s);",
+                parameterizedGeneratedTypeNameForBinding(binding),
+                Joiner.on(", ").join(params.keySet()));
+            break;
+          default:
+            throw new AssertionError();
+        }
+        break;
+      default: // do nothing.
+    }
+
+    List<Snippet> parameters = Lists.newArrayList();
+    for (DependencyRequest dependency : binding.dependencies()) {
+      parameters.add(frameworkTypeUsageStatement(
+          Snippet.format(fields.get(dependency.bindingKey()).name()), dependency.kind()));
+    }
+    Snippet parametersSnippet = makeParametersSnippet(parameters);
+
+    if (binding.bindingKind().equals(PROVISION)) {
+      Snippet providesMethodInvocation = Snippet.format("%s.%s(%s)",
+          binding.bindingElement().getModifiers().contains(STATIC)
+              ? ClassName.fromTypeElement(binding.bindingTypeElement())
+              : "module",
+          binding.bindingElement().getSimpleName(),
+          parametersSnippet);
+
+      if (binding.provisionType().equals(SET)) {
+        TypeName paramTypeName = TypeNames.forTypeMirror(
+            MoreTypes.asDeclared(keyType).getTypeArguments().get(0));
+        // TODO(cgruber): only be explicit with the parameter if paramType contains wildcards.
+        getMethodWriter.body().addSnippet("return %s.<%s>singleton(%s);",
+            ClassName.fromClass(Collections.class), paramTypeName, providesMethodInvocation);
+      } else if (binding.nullableType().isPresent()
+          || nullableValidationType.equals(Diagnostic.Kind.WARNING)) {
+        if (binding.nullableType().isPresent()) {
+          getMethodWriter.annotate(
+              (ClassName) TypeNames.forTypeMirror(binding.nullableType().get()));
+        }
+        getMethodWriter.body().addSnippet("return %s;", providesMethodInvocation);
+      } else {
+        StringLiteral failMsg =
+            StringLiteral.forValue(CANNOT_RETURN_NULL_FROM_NON_NULLABLE_PROVIDES_METHOD);
+        getMethodWriter.body().addSnippet(Snippet.format(Joiner.on('\n').join(
+            "%s provided = %s;",
+            "if (provided == null) {",
+            "  throw new NullPointerException(%s);",
+            "}",
+            "return provided;"),
+            getMethodWriter.returnType(),
+            providesMethodInvocation,
+            failMsg));
+      }
+    } else if (binding.membersInjectionRequest().isPresent()) {
+      getMethodWriter.body().addSnippet("%1$s instance = new %1$s(%2$s);",
+          providedTypeName, parametersSnippet);
+      getMethodWriter.body().addSnippet("membersInjector.injectMembers(instance);");
+      getMethodWriter.body().addSnippet("return instance;");
+    } else {
+      getMethodWriter.body()
+          .addSnippet("return new %s(%s);", providedTypeName, parametersSnippet);
+    }
+
+    // TODO(gak): write a sensible toString
+    return ImmutableSet.of(writer);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/Formatter.java b/compiler/src/main/java/dagger/internal/codegen/Formatter.java
new file mode 100644
index 0000000..880b787
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/Formatter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Function;
+
+/**
+ * A formatter which transforms an instance of a particular type into a string
+ * representation.
+ *
+ * @param <T> the type of the object to be transformed.
+ * @author Christian Gruber
+ * @since 2.0
+ */
+abstract class Formatter<T> implements Function<T, String> {
+
+  /**
+   * Performs the transformation of an object into a string representation.
+   */
+  public abstract String format(T object);
+
+  /**
+   * Performs the transformation of an object into a string representation in
+   * conformity with the {@link Function}{@code <T, String>} contract, delegating
+   * to {@link #format(Object)}.
+   *
+   * @deprecated Call {@link #format(T)} instead.  This method exists to make
+   * formatters easy to use when functions are required, but shouldn't be called directly.
+   */
+  @SuppressWarnings("javadoc")
+  @Deprecated
+  @Override final public String apply(T object) {
+    return format(object);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/FrameworkField.java b/compiler/src/main/java/dagger/internal/codegen/FrameworkField.java
new file mode 100644
index 0000000..38e8f02
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/FrameworkField.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ImmutableSet;
+import dagger.MembersInjector;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementKindVisitor6;
+
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static dagger.internal.codegen.ContributionBinding.contributionTypeFor;
+
+/**
+ * A value object that represents a field used by Dagger-generated code.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+@AutoValue
+abstract class FrameworkField {
+  // TODO(gak): reexamine the this class and how consistently we're using it and its creation
+  // methods
+  static FrameworkField createWithTypeFromKey(
+      Class<?> frameworkClass, BindingKey bindingKey, String name) {
+    String suffix = frameworkClass.getSimpleName();
+    ParameterizedTypeName frameworkType = ParameterizedTypeName.create(
+        ClassName.fromClass(frameworkClass),
+        TypeNames.forTypeMirror(bindingKey.key().type()));
+    return new AutoValue_FrameworkField(frameworkClass, frameworkType, bindingKey,
+        name.endsWith(suffix) ? name : name + suffix);
+  }
+
+  private static FrameworkField createForMapBindingContribution(
+      Class<?> frameworkClass, BindingKey bindingKey, String name) {
+    TypeMirror mapValueType =
+        MoreTypes.asDeclared(bindingKey.key().type()).getTypeArguments().get(1);
+    return new AutoValue_FrameworkField(frameworkClass,
+        (ParameterizedTypeName) TypeNames.forTypeMirror(mapValueType),
+        bindingKey,
+        name);
+  }
+
+  static FrameworkField createForSyntheticContributionBinding(
+      int contributionNumber, ContributionBinding contributionBinding) {
+    switch (contributionBinding.contributionType()) {
+      case MAP:
+        return createForMapBindingContribution(
+            contributionBinding.frameworkClass(),
+            contributionBinding.bindingKey(),
+            KeyVariableNamer.INSTANCE.apply(contributionBinding.key())
+                + "Contribution"
+                + contributionNumber);
+
+      case SET:
+      case UNIQUE:
+        return createWithTypeFromKey(
+            contributionBinding.frameworkClass(),
+            contributionBinding.bindingKey(),
+            KeyVariableNamer.INSTANCE.apply(contributionBinding.key())
+                + "Contribution"
+                + contributionNumber);
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  static FrameworkField createForResolvedBindings(ResolvedBindings resolvedBindings) {
+    BindingKey bindingKey = resolvedBindings.bindingKey();
+    switch (bindingKey.kind()) {
+      case CONTRIBUTION:
+        ImmutableSet<ContributionBinding> contributionBindings =
+            resolvedBindings.contributionBindings();
+        switch (contributionTypeFor(contributionBindings)) {
+          case SET:
+          case MAP:
+            return createWithTypeFromKey(
+                FrameworkField.frameworkClassForResolvedBindings(resolvedBindings),
+                bindingKey,
+                KeyVariableNamer.INSTANCE.apply(bindingKey.key()));
+          case UNIQUE:
+            ContributionBinding binding = getOnlyElement(contributionBindings);
+            return createWithTypeFromKey(
+                FrameworkField.frameworkClassForResolvedBindings(resolvedBindings),
+                bindingKey,
+                BINDING_ELEMENT_NAME.visit(binding.bindingElement()));
+          default:
+            throw new AssertionError();
+        }
+      case MEMBERS_INJECTION:
+        return createWithTypeFromKey(
+            MembersInjector.class,
+            bindingKey,
+            CaseFormat.UPPER_CAMEL.to(
+                CaseFormat.LOWER_CAMEL,
+                resolvedBindings
+                    .membersInjectionBinding()
+                    .get()
+                    .bindingElement()
+                    .getSimpleName()
+                    .toString()));
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private static final ElementVisitor<String, Void> BINDING_ELEMENT_NAME =
+      new ElementKindVisitor6<String, Void>() {
+        @Override
+        public String visitExecutableAsConstructor(ExecutableElement e, Void p) {
+          return visit(e.getEnclosingElement());
+        }
+
+        @Override
+        public String visitExecutableAsMethod(ExecutableElement e, Void p) {
+          return e.getSimpleName().toString();
+        }
+
+        @Override
+        public String visitType(TypeElement e, Void p) {
+          return CaseFormat.UPPER_CAMEL.to(
+              CaseFormat.LOWER_CAMEL, e.getSimpleName().toString());
+        }
+      };
+
+  static Class<?> frameworkClassForResolvedBindings(ResolvedBindings resolvedBindings) {
+    switch (resolvedBindings.bindingKey().kind()) {
+      case CONTRIBUTION:
+        return any(resolvedBindings.contributionBindings(), Binding.Type.PRODUCTION)
+            ? Binding.Type.PRODUCTION.frameworkClass()
+            : Binding.Type.PROVISION.frameworkClass();
+      case MEMBERS_INJECTION:
+        return MembersInjector.class;
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  abstract Class<?> frameworkClass();
+  abstract ParameterizedTypeName frameworkType();
+  abstract BindingKey bindingKey();
+  abstract String name();
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectBindingRegistry.java b/compiler/src/main/java/dagger/internal/codegen/InjectBindingRegistry.java
new file mode 100644
index 0000000..f7ca429
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectBindingRegistry.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+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 dagger.Component;
+import dagger.Provides;
+import dagger.internal.codegen.writer.ClassName;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+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.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+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.SourceFiles.generatedClassNameForBinding;
+
+/**
+ * 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 InjectBindingRegistry {
+  private final Elements elements;
+  private final Types types;
+  private final Messager messager;
+  private final ProvisionBinding.Factory provisionBindingFactory;
+  private final MembersInjectionBinding.Factory membersInjectionBindingFactory;
+
+  final class BindingsCollection<B extends Binding> {
+    private final Map<Key, B> bindingsByKey = Maps.newLinkedHashMap();
+    private final Deque<B> bindingsRequiringGeneration = new ArrayDeque<>();
+    private final Set<Key> materializedBindingKeys = Sets.newLinkedHashSet();
+
+    void generateBindings(SourceFileGenerator<B> generator) throws SourceFileGenerationException {
+      for (B binding = bindingsRequiringGeneration.poll();
+          binding != null;
+          binding = bindingsRequiringGeneration.poll()) {
+        checkState(!binding.hasNonDefaultTypeParameters());
+        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, ClassName factoryName, boolean explicit) {
+      tryToCacheBinding(binding);
+      tryToGenerateBinding(binding, factoryName, explicit);
+    }
+
+    /**
+     * 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, ClassName factoryName, boolean explicit) {
+      if (shouldGenerateBinding(binding, factoryName)) {
+        bindingsRequiringGeneration.offer(binding);
+        if (!explicit) {
+          messager.printMessage(Kind.NOTE, String.format(
+              "Generating a MembersInjector or Factory for %s. "
+                    + "Prefer to run the dagger processor over that class instead.",
+              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.hasNonDefaultTypeParameters()
+          && elements.getTypeElement(factoryName.canonicalName()) == 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.hasNonDefaultTypeParameters()
+          || binding.bindingTypeElement().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<>();
+  private final BindingsCollection<MembersInjectionBinding> membersInjectionBindings =
+      new BindingsCollection<>();
+
+  InjectBindingRegistry(Elements elements,
+      Types types,
+      Messager messager,
+      ProvisionBinding.Factory provisionBindingFactory,
+      MembersInjectionBinding.Factory membersInjectionBindingFactory) {
+    this.elements = elements;
+    this.types = types;
+    this.messager = messager;
+    this.provisionBindingFactory = provisionBindingFactory;
+    this.membersInjectionBindingFactory = membersInjectionBindingFactory;
+  }
+
+  /**
+   * 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.
+   */
+  void generateSourcesForRequiredBindings(FactoryGenerator factoryGenerator,
+      MembersInjectorGenerator membersInjectorGenerator) throws SourceFileGenerationException {
+    provisionBindings.generateBindings(factoryGenerator);
+    membersInjectionBindings.generateBindings(membersInjectorGenerator);
+  }
+
+  ProvisionBinding registerBinding(ProvisionBinding binding) {
+    return registerBinding(binding, true);
+  }
+
+  MembersInjectionBinding registerBinding(MembersInjectionBinding binding) {
+    return registerBinding(binding, true);
+  }
+
+  /**
+   * Registers the binding for generation & later lookup. If the binding is resolved, we also
+   * attempt to register an unresolved version of it.
+   */
+  private ProvisionBinding registerBinding(ProvisionBinding binding, boolean explicit) {
+    ClassName factoryName = generatedClassNameForBinding(binding);
+    provisionBindings.tryRegisterBinding(binding, factoryName, explicit);
+    if (binding.hasNonDefaultTypeParameters()) {
+      provisionBindings.tryToGenerateBinding(provisionBindingFactory.unresolve(binding),
+          factoryName, explicit);
+    }
+    return binding;
+  }
+
+  /**
+   * Registers the binding for generation & later lookup. If the binding is resolved, we also
+   * attempt to register an unresolved version of it.
+   */
+  private MembersInjectionBinding registerBinding(
+      MembersInjectionBinding binding, boolean explicit) {
+    ClassName membersInjectorName = generatedClassNameForBinding(binding);
+    membersInjectionBindings.tryRegisterBinding(binding, membersInjectorName, explicit);
+    if (binding.hasNonDefaultTypeParameters()) {
+      membersInjectionBindings.tryToGenerateBinding(
+          membersInjectionBindingFactory.unresolve(binding), membersInjectorName, explicit);
+    }
+    return binding;
+  }
+
+  Optional<ProvisionBinding> getOrFindProvisionBinding(Key key) {
+    checkNotNull(key);
+    if (!key.isValidImplicitProvisionKey(types)) {
+      return Optional.absent();
+    }
+    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()));
+    List<ExecutableElement> constructors =
+        ElementFilter.constructorsIn(element.getEnclosedElements());
+    ImmutableSet<ExecutableElement> injectConstructors = FluentIterable.from(constructors)
+        .filter(new Predicate<ExecutableElement>() {
+          @Override public boolean apply(ExecutableElement input) {
+            return isAnnotationPresent(input, Inject.class);
+          }
+        }).toSet();
+    switch (injectConstructors.size()) {
+      case 0:
+        // No constructor found.
+        return Optional.absent();
+      case 1:
+        ProvisionBinding constructorBinding = provisionBindingFactory.forInjectConstructor(
+            Iterables.getOnlyElement(injectConstructors), Optional.of(key.type()));
+        return Optional.of(registerBinding(constructorBinding, false));
+      default:
+        throw new IllegalStateException("Found multiple @Inject constructors: "
+            + injectConstructors);
+    }
+  }
+
+  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 binding;
+    }
+    return registerBinding(membersInjectionBindingFactory.forInjectedType(
+        MoreTypes.asDeclared(key.type()), Optional.of(key.type())), false);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectConstructorValidator.java b/compiler/src/main/java/dagger/internal/codegen/InjectConstructorValidator.java
new file mode 100644
index 0000000..11cd066
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectConstructorValidator.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static dagger.internal.codegen.ErrorMessages.INJECT_CONSTRUCTOR_ON_ABSTRACT_CLASS;
+import static dagger.internal.codegen.ErrorMessages.INJECT_CONSTRUCTOR_ON_INNER_CLASS;
+import static dagger.internal.codegen.ErrorMessages.INJECT_INTO_PRIVATE_CLASS;
+import static dagger.internal.codegen.ErrorMessages.INJECT_ON_PRIVATE_CONSTRUCTOR;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_INJECT_CONSTRUCTORS;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_QUALIFIERS;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_SCOPES;
+import static dagger.internal.codegen.ErrorMessages.QUALIFIER_ON_INJECT_CONSTRUCTOR;
+import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
+import static dagger.internal.codegen.InjectionAnnotations.getScopes;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Inject} constructors.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class InjectConstructorValidator {
+  ValidationReport<TypeElement> validate(ExecutableElement constructorElement) {
+    ValidationReport.Builder<TypeElement> builder =
+        ValidationReport.about(MoreElements.asType(constructorElement.getEnclosingElement()));
+    if (constructorElement.getModifiers().contains(PRIVATE)) {
+      builder.addError(INJECT_ON_PRIVATE_CONSTRUCTOR, constructorElement);
+    }
+
+    for (AnnotationMirror qualifier : getQualifiers(constructorElement)) {
+      builder.addError(QUALIFIER_ON_INJECT_CONSTRUCTOR, constructorElement, qualifier);
+    }
+
+    for (VariableElement parameter : constructorElement.getParameters()) {
+      ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(parameter);
+      if (qualifiers.size() > 1) {
+        for (AnnotationMirror qualifier : qualifiers) {
+          builder.addError(MULTIPLE_QUALIFIERS, constructorElement, qualifier);
+        }
+      }
+    }
+
+    TypeElement enclosingElement =
+        MoreElements.asType(constructorElement.getEnclosingElement());
+    Set<Modifier> typeModifiers = enclosingElement.getModifiers();
+
+    if (typeModifiers.contains(PRIVATE)) {
+      builder.addError(INJECT_INTO_PRIVATE_CLASS, constructorElement);
+    }
+
+    if (typeModifiers.contains(ABSTRACT)) {
+      builder.addError(INJECT_CONSTRUCTOR_ON_ABSTRACT_CLASS, constructorElement);
+    }
+
+    if (enclosingElement.getNestingKind().isNested()
+        && !typeModifiers.contains(STATIC)) {
+      builder.addError(INJECT_CONSTRUCTOR_ON_INNER_CLASS, constructorElement);
+    }
+
+    // This is computationally expensive, but probably preferable to a giant index
+    FluentIterable<ExecutableElement> injectConstructors = FluentIterable.from(
+        ElementFilter.constructorsIn(enclosingElement.getEnclosedElements()))
+            .filter(new Predicate<ExecutableElement>() {
+              @Override public boolean apply(ExecutableElement input) {
+                return isAnnotationPresent(input, Inject.class);
+              }
+            });
+
+    if (injectConstructors.size() > 1) {
+      builder.addError(MULTIPLE_INJECT_CONSTRUCTORS, constructorElement);
+    }
+
+    ImmutableSet<? extends AnnotationMirror> scopes = getScopes(enclosingElement);
+    if (scopes.size() > 1) {
+      for (AnnotationMirror scope : scopes) {
+        builder.addError(MULTIPLE_SCOPES, enclosingElement, scope);
+      }
+    }
+
+    return builder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectFieldValidator.java b/compiler/src/main/java/dagger/internal/codegen/InjectFieldValidator.java
new file mode 100644
index 0000000..e30678a
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectFieldValidator.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.VariableElement;
+import javax.tools.Diagnostic.Kind;
+
+import static dagger.internal.codegen.ErrorMessages.FINAL_INJECT_FIELD;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_QUALIFIERS;
+import static dagger.internal.codegen.ErrorMessages.PRIVATE_INJECT_FIELD;
+import static dagger.internal.codegen.ErrorMessages.STATIC_INJECT_FIELD;
+import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Inject} fields.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class InjectFieldValidator {
+  private Kind privateMemberValidationKind;
+  private Kind staticMemberValidationKind;
+  
+  public InjectFieldValidator(
+      Kind privateMemberValidationKind, Kind staticMemberValidationKind) {
+    this.privateMemberValidationKind = privateMemberValidationKind;
+    this.staticMemberValidationKind = staticMemberValidationKind;
+  }
+
+  ValidationReport<VariableElement> validate(VariableElement fieldElement) {
+    ValidationReport.Builder<VariableElement> builder = ValidationReport.about(fieldElement);
+    Set<Modifier> modifiers = fieldElement.getModifiers();
+    if (modifiers.contains(FINAL)) {
+      builder.addError(FINAL_INJECT_FIELD, fieldElement);
+    }
+
+    if (modifiers.contains(PRIVATE)) {
+      builder.addItem(PRIVATE_INJECT_FIELD, privateMemberValidationKind, fieldElement);
+    }
+
+    if (modifiers.contains(STATIC)) {
+      builder.addItem(STATIC_INJECT_FIELD, staticMemberValidationKind, fieldElement);
+    }
+    
+    ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(fieldElement);
+    if (qualifiers.size() > 1) {
+      for (AnnotationMirror qualifier : qualifiers) {
+        builder.addError(MULTIPLE_QUALIFIERS, fieldElement, qualifier);
+      }
+    }
+
+    return builder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectMethodValidator.java b/compiler/src/main/java/dagger/internal/codegen/InjectMethodValidator.java
new file mode 100644
index 0000000..a716b7d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectMethodValidator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.VariableElement;
+import javax.tools.Diagnostic.Kind;
+
+import static dagger.internal.codegen.ErrorMessages.ABSTRACT_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.GENERIC_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_QUALIFIERS;
+import static dagger.internal.codegen.ErrorMessages.PRIVATE_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.STATIC_INJECT_METHOD;
+import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Inject} methods.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class InjectMethodValidator {
+  private Kind privateMemberValidationKind;
+  private Kind staticMemberValidationKind;
+  
+  public InjectMethodValidator(
+      Kind privateMemberValidationKind, Kind staticMemberValidationKind) {
+    this.privateMemberValidationKind = privateMemberValidationKind;
+    this.staticMemberValidationKind = staticMemberValidationKind;
+  }
+
+  ValidationReport<ExecutableElement> validate(ExecutableElement methodElement) {
+    ValidationReport.Builder<ExecutableElement> builder = ValidationReport.about(methodElement);
+    Set<Modifier> modifiers = methodElement.getModifiers();
+    if (modifiers.contains(ABSTRACT)) {
+      builder.addError(ABSTRACT_INJECT_METHOD, methodElement);
+    }
+
+    if (modifiers.contains(PRIVATE)) {
+      builder.addItem(PRIVATE_INJECT_METHOD, privateMemberValidationKind, methodElement);
+    }
+    
+    if (modifiers.contains(STATIC)) {
+      builder.addItem(STATIC_INJECT_METHOD, staticMemberValidationKind, methodElement);
+    }
+
+    if (!methodElement.getTypeParameters().isEmpty()) {
+      builder.addError(GENERIC_INJECT_METHOD, methodElement);
+    }
+
+    for (VariableElement parameter : methodElement.getParameters()) {
+      ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(parameter);
+      if (qualifiers.size() > 1) {
+        for (AnnotationMirror qualifier : qualifiers) {
+          builder.addError(MULTIPLE_QUALIFIERS, methodElement, qualifier);
+        }
+      }
+    }
+
+    return builder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/InjectProcessingStep.java
new file mode 100644
index 0000000..dac904f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectProcessingStep.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+import javax.annotation.processing.Messager;
+import javax.inject.Inject;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementKindVisitor6;
+
+/**
+ * An annotation processor for generating Dagger implementation code based on the {@link Inject}
+ * annotation.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class InjectProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
+  private final Messager messager;
+  private final InjectConstructorValidator constructorValidator;
+  private final InjectFieldValidator fieldValidator;
+  private final InjectMethodValidator methodValidator;
+  private final ProvisionBinding.Factory provisionBindingFactory;
+  private final MembersInjectionBinding.Factory membersInjectionBindingFactory;
+  private final InjectBindingRegistry injectBindingRegistry;
+
+  InjectProcessingStep(
+      Messager messager,
+      InjectConstructorValidator constructorValidator,
+      InjectFieldValidator fieldValidator,
+      InjectMethodValidator methodValidator,
+      ProvisionBinding.Factory provisionBindingFactory,
+      MembersInjectionBinding.Factory membersInjectionBindingFactory,
+      InjectBindingRegistry factoryRegistrar) {
+    this.messager = messager;
+    this.constructorValidator = constructorValidator;
+    this.fieldValidator = fieldValidator;
+    this.methodValidator = methodValidator;
+    this.provisionBindingFactory = provisionBindingFactory;
+    this.membersInjectionBindingFactory = membersInjectionBindingFactory;
+    this.injectBindingRegistry = factoryRegistrar;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.<Class<? extends Annotation>>of(Inject.class);
+  }
+
+  @Override
+  public Set<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    ImmutableSet.Builder<Element> rejectedElements = ImmutableSet.builder();
+    // TODO(gak): add some error handling for bad source files
+    final ImmutableSet.Builder<ProvisionBinding> provisions = ImmutableSet.builder();
+    // TODO(gak): instead, we should collect reports by type and check later
+    final ImmutableSet.Builder<DeclaredType> membersInjectedTypes = ImmutableSet.builder();
+
+    for (Element injectElement : elementsByAnnotation.get(Inject.class)) {
+      try {
+        injectElement.accept(
+            new ElementKindVisitor6<Void, Void>() {
+              @Override
+              public Void visitExecutableAsConstructor(
+                  ExecutableElement constructorElement, Void v) {
+                ValidationReport<TypeElement> report =
+                    constructorValidator.validate(constructorElement);
+
+                report.printMessagesTo(messager);
+
+                if (report.isClean()) {
+                  provisions.add(
+                      provisionBindingFactory.forInjectConstructor(
+                          constructorElement, Optional.<TypeMirror>absent()));
+                  DeclaredType type =
+                      MoreTypes.asDeclared(constructorElement.getEnclosingElement().asType());
+                  if (membersInjectionBindingFactory.hasInjectedMembers(type)) {
+                    membersInjectedTypes.add(type);
+                  }
+                }
+
+                return null;
+              }
+
+              @Override
+              public Void visitVariableAsField(VariableElement fieldElement, Void p) {
+                ValidationReport<VariableElement> report = fieldValidator.validate(fieldElement);
+
+                report.printMessagesTo(messager);
+
+                if (report.isClean()) {
+                  membersInjectedTypes.add(
+                      MoreTypes.asDeclared(fieldElement.getEnclosingElement().asType()));
+                }
+
+                return null;
+              }
+
+              @Override
+              public Void visitExecutableAsMethod(ExecutableElement methodElement, Void p) {
+                ValidationReport<ExecutableElement> report =
+                    methodValidator.validate(methodElement);
+
+                report.printMessagesTo(messager);
+
+                if (report.isClean()) {
+                  membersInjectedTypes.add(
+                      MoreTypes.asDeclared(methodElement.getEnclosingElement().asType()));
+                }
+
+                return null;
+              }
+            },
+            null);
+      } catch (TypeNotPresentException e) {
+        rejectedElements.add(injectElement);
+      }
+    }
+
+    for (DeclaredType injectedType : membersInjectedTypes.build()) {
+      injectBindingRegistry.registerBinding(membersInjectionBindingFactory.forInjectedType(
+          injectedType, Optional.<TypeMirror>absent()));
+    }
+
+    for (ProvisionBinding binding : provisions.build()) {
+      injectBindingRegistry.registerBinding(binding);
+    }
+    return rejectedElements.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/InjectionAnnotations.java b/compiler/src/main/java/dagger/internal/codegen/InjectionAnnotations.java
new file mode 100644
index 0000000..b3b245d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/InjectionAnnotations.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.AnnotationMirrors;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import javax.inject.Qualifier;
+import javax.inject.Scope;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Utilities relating to annotations defined in the {@code javax.inject} package.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class InjectionAnnotations {
+  static Optional<AnnotationMirror> getScopeAnnotation(Element e) {
+    checkNotNull(e);
+    ImmutableSet<? extends AnnotationMirror> scopeAnnotations = getScopes(e);
+    switch (scopeAnnotations.size()) {
+      case 0:
+        return Optional.absent();
+      case 1:
+        return Optional.<AnnotationMirror>of(scopeAnnotations.iterator().next());
+      default:
+        throw new IllegalArgumentException(
+            e + " was annotated with more than one @Scope annotation");
+    }
+  }
+
+  static Optional<AnnotationMirror> getQualifier(Element e) {
+    checkNotNull(e);
+    ImmutableSet<? extends AnnotationMirror> qualifierAnnotations = getQualifiers(e);
+    switch (qualifierAnnotations.size()) {
+      case 0:
+        return Optional.absent();
+      case 1:
+        return Optional.<AnnotationMirror>of(qualifierAnnotations.iterator().next());
+      default:
+        throw new IllegalArgumentException(
+            e + " was annotated with more than one @Qualifier annotation");
+    }
+  }
+
+  static ImmutableSet<? extends AnnotationMirror> getQualifiers(Element element) {
+    return AnnotationMirrors.getAnnotatedAnnotations(element, Qualifier.class);
+  }
+
+  static ImmutableSet<? extends AnnotationMirror> getScopes(Element element) {
+    return AnnotationMirrors.getAnnotatedAnnotations(element, Scope.class);
+  }
+
+  private InjectionAnnotations() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/Key.java b/compiler/src/main/java/dagger/internal/codegen/Key.java
new file mode 100644
index 0000000..f0bd3a0
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/Key.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.AnnotationMirrors;
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Provides;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.Produces;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.inject.Qualifier;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.PrimitiveType;
+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;
+
+import static com.google.auto.common.MoreTypes.asExecutable;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
+import static dagger.internal.codegen.MapKeys.getMapKey;
+import static dagger.internal.codegen.MapKeys.getUnwrappedMapKeyType;
+import static dagger.internal.codegen.Util.unwrapOptionalEquivalence;
+import static dagger.internal.codegen.Util.wrapOptionalInEquivalence;
+import static javax.lang.model.element.ElementKind.METHOD;
+
+/**
+ * Represents a unique combination of {@linkplain TypeMirror type} and
+ * {@linkplain Qualifier qualifier} to which binding can occur.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class Key {
+  /**
+   * A {@link javax.inject.Qualifier} annotation that provides a unique namespace prefix
+   * for the type of this key.
+   *
+   * Despite documentation in {@link AnnotationMirror}, equals and hashCode aren't implemented
+   * to represent logical equality, so {@link AnnotationMirrors#equivalence()}
+   * provides this facility.
+   */
+  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedQualifier();
+
+  /**
+   * The type represented by this key.
+   *
+   * As documented in {@link TypeMirror}, equals and hashCode aren't implemented to represent
+   * logical equality, so {@link MoreTypes#equivalence()} wraps this type.
+   */
+  abstract Equivalence.Wrapper<TypeMirror> wrappedType();
+
+  Optional<AnnotationMirror> qualifier() {
+    return unwrapOptionalEquivalence(wrappedQualifier());
+  }
+
+  TypeMirror type() {
+    return wrappedType().get();
+  }
+
+  private static TypeMirror normalize(Types types, TypeMirror type) {
+    TypeKind kind = type.getKind();
+    return kind.isPrimitive() ? types.boxedClass((PrimitiveType) type).asType() : type;
+  }
+
+  Key withType(Types types, TypeMirror newType) {
+    return new AutoValue_Key(wrappedQualifier(),
+        MoreTypes.equivalence().wrap(normalize(types, newType)));
+  }
+
+  boolean isValidMembersInjectionKey() {
+    return !qualifier().isPresent();
+  }
+
+  /**
+   * Returns true if the key is valid as an implicit key (that is, if it's valid for a just-in-time
+   * binding by discovering an {@code @Inject} constructor).
+   */
+  boolean isValidImplicitProvisionKey(final Types types) {
+    // Qualifiers disqualify implicit provisioning.
+    if (qualifier().isPresent()) {
+      return false;
+    }
+
+    return type().accept(new SimpleTypeVisitor6<Boolean, Void>() {
+      @Override protected Boolean defaultAction(TypeMirror e, Void p) {
+        return false; // Only declared types are allowed.
+      }
+
+      @Override public Boolean visitDeclared(DeclaredType type, Void ignored) {
+        // Non-classes or abstract classes aren't allowed.
+        TypeElement element = MoreElements.asType(type.asElement());
+        if (!element.getKind().equals(ElementKind.CLASS)
+            || element.getModifiers().contains(Modifier.ABSTRACT)) {
+          return false;
+        }
+
+        // If the key has type arguments, validate that each type argument is declared.
+        // Otherwise the type argument may be a wildcard (or other type), and we can't
+        // resolve that to actual types.
+        for (TypeMirror arg : type.getTypeArguments()) {
+          if (arg.getKind() != TypeKind.DECLARED) {
+            return false;
+          }
+        }
+
+        // Also validate that the key is not the erasure of a generic type.
+        // If it is, that means the user referred to Foo<T> as just 'Foo',
+        // which we don't allow.  (This is a judgement call -- we *could*
+        // allow it and instantiate the type bounds... but we don't.)
+        return MoreTypes.asDeclared(element.asType()).getTypeArguments().isEmpty()
+            || !types.isSameType(types.erasure(element.asType()), type());
+      }
+    }, null);
+  }
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(Key.class)
+        .omitNullValues()
+        .add("qualifier", qualifier().orNull())
+        .add("type", type())
+        .toString();
+  }
+
+  static final class Factory {
+    private final Types types;
+    private final Elements elements;
+
+    Factory(Types types, Elements elements) {
+      this.types = checkNotNull(types);
+      this.elements = checkNotNull(elements);
+    }
+
+    private TypeElement getSetElement() {
+      return elements.getTypeElement(Set.class.getCanonicalName());
+    }
+
+    private TypeElement getMapElement() {
+      return elements.getTypeElement(Map.class.getCanonicalName());
+    }
+
+    private TypeElement getProviderElement() {
+      return elements.getTypeElement(Provider.class.getCanonicalName());
+    }
+
+    private TypeElement getProducerElement() {
+      return elements.getTypeElement(Producer.class.getCanonicalName());
+    }
+
+    private TypeElement getClassElement(Class<?> cls) {
+      return elements.getTypeElement(cls.getCanonicalName());
+    }
+
+    Key forComponentMethod(ExecutableElement componentMethod) {
+      checkNotNull(componentMethod);
+      checkArgument(componentMethod.getKind().equals(METHOD));
+      TypeMirror returnType = normalize(types, componentMethod.getReturnType());
+      return forMethod(componentMethod, returnType);
+    }
+
+    Key forProductionComponentMethod(ExecutableElement componentMethod) {
+      checkNotNull(componentMethod);
+      checkArgument(componentMethod.getKind().equals(METHOD));
+      TypeMirror returnType = normalize(types, componentMethod.getReturnType());
+      TypeMirror keyType = returnType;
+      if (MoreTypes.isTypeOf(ListenableFuture.class, returnType)) {
+        keyType = Iterables.getOnlyElement(MoreTypes.asDeclared(returnType).getTypeArguments());
+      }
+      return forMethod(componentMethod, keyType);
+    }
+
+    Key forSubcomponentBuilderMethod(
+        ExecutableElement subcomponentBuilderMethod, DeclaredType declaredContainer) {
+      checkNotNull(subcomponentBuilderMethod);
+      checkArgument(subcomponentBuilderMethod.getKind().equals(METHOD));
+      ExecutableType resolvedMethod =
+          asExecutable(types.asMemberOf(declaredContainer, subcomponentBuilderMethod));
+      TypeMirror returnType = normalize(types, resolvedMethod.getReturnType());
+      return forMethod(subcomponentBuilderMethod, returnType);
+    }
+
+    Key forProvidesMethod(ExecutableType executableType, ExecutableElement method) {
+      checkNotNull(method);
+      checkArgument(method.getKind().equals(METHOD));
+      Provides providesAnnotation = method.getAnnotation(Provides.class);
+      checkArgument(providesAnnotation != null);
+      TypeMirror returnType = normalize(types, executableType.getReturnType());
+      TypeMirror keyType =
+          providesOrProducesKeyType(
+              returnType,
+              method,
+              Optional.of(providesAnnotation.type()),
+              Optional.<Produces.Type>absent());
+      return forMethod(method, keyType);
+    }
+
+    // TODO(user): Reconcile this method with forProvidesMethod when Provides.Type and
+    // Produces.Type are no longer different.
+    Key forProducesMethod(ExecutableType executableType, ExecutableElement method) {
+      checkNotNull(method);
+      checkArgument(method.getKind().equals(METHOD));
+      Produces producesAnnotation = method.getAnnotation(Produces.class);
+      checkArgument(producesAnnotation != null);
+      TypeMirror returnType = normalize(types, executableType.getReturnType());
+      TypeMirror unfuturedType = returnType;
+      if (MoreTypes.isTypeOf(ListenableFuture.class, returnType)) {
+        unfuturedType =
+            Iterables.getOnlyElement(MoreTypes.asDeclared(returnType).getTypeArguments());
+      }
+      TypeMirror keyType =
+          providesOrProducesKeyType(
+              unfuturedType,
+              method,
+              Optional.<Provides.Type>absent(),
+              Optional.of(producesAnnotation.type()));
+      return forMethod(method, keyType);
+    }
+
+    private TypeMirror providesOrProducesKeyType(
+        TypeMirror returnType,
+        ExecutableElement method,
+        Optional<Provides.Type> providesType,
+        Optional<Produces.Type> producesType) {
+      switch (providesType.isPresent()
+          ? providesType.get()
+          : Provides.Type.valueOf(producesType.get().name())) {
+        case UNIQUE:
+          return returnType;
+        case SET:
+          return types.getDeclaredType(getSetElement(), returnType);
+        case MAP:
+          return mapOfFactoryType(
+              method,
+              returnType,
+              providesType.isPresent() ? getProviderElement() : getProducerElement());
+        case SET_VALUES:
+          // TODO(gak): do we want to allow people to use "covariant return" here?
+          checkArgument(MoreTypes.isType(returnType) && MoreTypes.isTypeOf(Set.class, returnType));
+          return returnType;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    private TypeMirror mapOfFactoryType(
+        ExecutableElement method, TypeMirror valueType, TypeElement factoryType) {
+      TypeMirror mapKeyType = mapKeyType(method);
+      TypeMirror mapValueFactoryType = types.getDeclaredType(factoryType, valueType);
+      return types.getDeclaredType(getMapElement(), mapKeyType, mapValueFactoryType);
+    }
+
+    private TypeMirror mapKeyType(ExecutableElement method) {
+      AnnotationMirror mapKeyAnnotation = getMapKey(method).get();
+      return MapKeys.unwrapValue(mapKeyAnnotation).isPresent()
+          ? getUnwrappedMapKeyType(mapKeyAnnotation.getAnnotationType(), types)
+          : mapKeyAnnotation.getAnnotationType();
+    }
+
+    private Key forMethod(ExecutableElement method, TypeMirror keyType) {
+      return new AutoValue_Key(
+          wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), getQualifier(method)),
+          MoreTypes.equivalence().wrap(keyType));
+    }
+
+    Key forInjectConstructorWithResolvedType(TypeMirror type) {
+      return new AutoValue_Key(
+          Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+          MoreTypes.equivalence().wrap(type));
+    }
+
+    Key forComponent(TypeMirror type) {
+      return new AutoValue_Key(
+          Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+          MoreTypes.equivalence().wrap(normalize(types, type)));
+    }
+
+    Key forMembersInjectedType(TypeMirror type) {
+      return new AutoValue_Key(
+          Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+          MoreTypes.equivalence().wrap(normalize(types, type)));
+    }
+
+    Key forQualifiedType(Optional<AnnotationMirror> qualifier, TypeMirror type) {
+      return new AutoValue_Key(
+          wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), qualifier),
+          MoreTypes.equivalence().wrap(normalize(types, type)));
+    }
+
+    /**
+     * Optionally extract a {@link Key} for the underlying provision binding(s) if such a
+     * valid key can be inferred from the given key.  Specifically, if the key represents a
+     * {@link Map}{@code <K, V>}, a key of {@code Map<K, Provider<V>>} will be returned.
+     */
+    Optional<Key> implicitMapProviderKeyFrom(Key possibleMapKey) {
+      return maybeWrapMapValue(possibleMapKey, Provider.class);
+    }
+
+    /**
+     * Optionally extract a {@link Key} for the underlying production binding(s) if such a
+     * valid key can be inferred from the given key.  Specifically, if the key represents a
+     * {@link Map}{@code <K, V>}, a key of {@code Map<K, Producer<V>>} will be returned.
+     */
+    Optional<Key> implicitMapProducerKeyFrom(Key possibleMapKey) {
+      return maybeWrapMapValue(possibleMapKey, Producer.class);
+    }
+
+    /**
+     * Returns a key of {@link Map}{@code <K, WrappingClass<V>>} if the input key represents a
+     * {@code Map<K, V>}.
+     */
+    private Optional<Key> maybeWrapMapValue(Key possibleMapKey, Class<?> wrappingClass) {
+      if (MoreTypes.isTypeOf(Map.class, possibleMapKey.type())) {
+        DeclaredType declaredMapType = MoreTypes.asDeclared(possibleMapKey.type());
+        TypeMirror mapValueType = Util.getValueTypeOfMap(declaredMapType);
+        if (!MoreTypes.isTypeOf(wrappingClass, mapValueType)) {
+          TypeMirror keyType = Util.getKeyTypeOfMap(declaredMapType);
+          TypeElement wrappingElement = getClassElement(wrappingClass);
+          if (wrappingElement == null) {
+            // This target might not be compiled with Producers, so wrappingClass might not have an
+            // associated element.
+            return Optional.absent();
+          }
+          DeclaredType wrappedType = types.getDeclaredType(wrappingElement, mapValueType);
+          TypeMirror mapType = types.getDeclaredType(getMapElement(), keyType, wrappedType);
+          return Optional.<Key>of(new AutoValue_Key(
+              possibleMapKey.wrappedQualifier(),
+              MoreTypes.equivalence().wrap(mapType)));
+        }
+      }
+      return Optional.absent();
+    }
+
+    /**
+     * Optionally extract a {@link Key} for a {@code Set<T>} if the given key is for
+     * {@code Set<Produced<T>>}.
+     */
+    Optional<Key> implicitSetKeyFromProduced(Key possibleSetOfProducedKey) {
+      if (MoreTypes.isTypeOf(Set.class, possibleSetOfProducedKey.type())) {
+        TypeMirror argType =
+            MoreTypes.asDeclared(possibleSetOfProducedKey.type()).getTypeArguments().get(0);
+        if (MoreTypes.isTypeOf(Produced.class, argType)) {
+          TypeMirror producedArgType = MoreTypes.asDeclared(argType).getTypeArguments().get(0);
+          TypeMirror setType = types.getDeclaredType(getSetElement(), producedArgType);
+          return Optional.of(possibleSetOfProducedKey.withType(types, setType));
+        }
+      }
+      return Optional.absent();
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/KeyFormatter.java b/compiler/src/main/java/dagger/internal/codegen/KeyFormatter.java
new file mode 100644
index 0000000..6e695f3
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/KeyFormatter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+/**
+ * Formats a {@link Key} into a {@link String} suitable for use in error messages
+ *
+ * @author Christian Gruber
+ * @since 2.0
+ */
+final class KeyFormatter extends Formatter<Key> {
+
+  @Override public String format(Key request) {
+    StringBuilder builder = new StringBuilder();
+    if (request.qualifier().isPresent()) {
+      builder.append(request.qualifier().get());
+      builder.append(' ');
+    }
+    builder.append(request.type()); // TODO(cgruber): Use TypeMirrorFormatter.
+    return builder.toString();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/KeyVariableNamer.java b/compiler/src/main/java/dagger/internal/codegen/KeyVariableNamer.java
new file mode 100644
index 0000000..5fe12b1
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/KeyVariableNamer.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Function;
+import java.util.Iterator;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+import static com.google.common.base.CaseFormat.LOWER_CAMEL;
+import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+
+/**
+ * Suggests a variable name for a type based on a {@link Key}. Prefer
+ * {@link DependencyVariableNamer} for cases where a specific {@link DependencyRequest} is present.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+enum KeyVariableNamer implements Function<Key, String> {
+  INSTANCE;
+
+  @Override
+  public String apply(Key key) {
+    StringBuilder builder = new StringBuilder();
+
+    if (key.qualifier().isPresent()) {
+      // TODO(gak): Use a better name for fields with qualifiers with members.
+      builder.append(key.qualifier().get().getAnnotationType().asElement().getSimpleName());
+    }
+
+    key.type().accept(new SimpleTypeVisitor6<Void, StringBuilder>() {
+      @Override
+      public Void visitDeclared(DeclaredType t, StringBuilder builder) {
+        builder.append(t.asElement().getSimpleName());
+        Iterator<? extends TypeMirror> argumentIterator = t.getTypeArguments().iterator();
+        if (argumentIterator.hasNext()) {
+          builder.append("Of");
+          TypeMirror first = argumentIterator.next();
+          first.accept(this, builder);
+          while (argumentIterator.hasNext()) {
+            builder.append("And");
+            argumentIterator.next().accept(this, builder);
+          }
+        }
+        return null;
+      }
+    }, builder);
+
+    return UPPER_CAMEL.to(LOWER_CAMEL, builder.toString());
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MapKeyGenerator.java b/compiler/src/main/java/dagger/internal/codegen/MapKeyGenerator.java
new file mode 100644
index 0000000..8d72e5e
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MapKeyGenerator.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoAnnotation;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import dagger.MapKey;
+import dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import dagger.internal.codegen.writer.TypeWriter;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.annotation.Generated;
+import javax.annotation.processing.Filer;
+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.type.DeclaredType;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+import static dagger.internal.codegen.MapKeys.getMapKeyCreatorClassName;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+/**
+ * Generates classes that create annotations required to instantiate {@link MapKey}s.
+ *
+ * @since 2.0
+ */
+final class MapKeyGenerator extends SourceFileGenerator<MapKeyCreatorSpecification> {
+
+  /**
+   * Specification of the {@link MapKey} annotation and the annotation type to generate.
+   */
+  @AutoValue
+  abstract static class MapKeyCreatorSpecification {
+    /**
+     * The {@link MapKey}-annotated annotation.
+     */
+    abstract TypeElement mapKeyElement();
+
+    /**
+     * The annotation type to write create methods for. For wrapped {@link MapKey}s, this is
+     * {@link #mapKeyElement()}. For unwrapped {@code MapKey}s whose single element is an
+     * annotation, this is that annotation element.
+     */
+    abstract TypeElement annotationElement();
+
+    /**
+     * Returns a specification for a wrapped {@link MapKey}-annotated annotation.
+     */
+    static MapKeyCreatorSpecification wrappedMapKey(TypeElement mapKeyElement) {
+      return new AutoValue_MapKeyGenerator_MapKeyCreatorSpecification(mapKeyElement, mapKeyElement);
+    }
+
+    /**
+     * Returns a specification for an unwrapped {@link MapKey}-annotated annotation whose single
+     * element is a nested annotation.
+     */
+    static MapKeyCreatorSpecification unwrappedMapKeyWithAnnotationValue(
+        TypeElement mapKeyElement, TypeElement annotationElement) {
+      return new AutoValue_MapKeyGenerator_MapKeyCreatorSpecification(
+          mapKeyElement, annotationElement);
+    }
+  }
+
+  MapKeyGenerator(Filer filer) {
+    super(filer);
+  }
+
+  @Override
+  ClassName nameGeneratedType(MapKeyCreatorSpecification mapKeyCreatorType) {
+    return getMapKeyCreatorClassName(mapKeyCreatorType.mapKeyElement());
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(MapKeyCreatorSpecification mapKeyCreatorType) {
+    return ImmutableSet.of(mapKeyCreatorType.mapKeyElement());
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(
+      MapKeyCreatorSpecification mapKeyCreatorType) {
+    return Optional.of(mapKeyCreatorType.mapKeyElement());
+  }
+
+  @Override
+  ImmutableSet<JavaWriter> write(
+      ClassName generatedTypeName, MapKeyCreatorSpecification mapKeyCreatorType) {
+    JavaWriter writer = JavaWriter.inPackage(generatedTypeName.packageName());
+    TypeWriter mapKeyCreatorWriter = writer.addClass(generatedTypeName.simpleName());
+    mapKeyCreatorWriter.annotate(Generated.class).setValue(ComponentProcessor.class.getName());
+    mapKeyCreatorWriter.addModifiers(PUBLIC, FINAL);
+
+    for (TypeElement annotationElement :
+        nestedAnnotationElements(mapKeyCreatorType.annotationElement())) {
+      writeCreateMethod(mapKeyCreatorWriter, annotationElement);
+    }
+
+    return ImmutableSet.of(writer);
+  }
+
+  private void writeCreateMethod(TypeWriter mapKeyCreatorWriter, TypeElement annotationElement) {
+    MethodWriter createMethod =
+        mapKeyCreatorWriter.addMethod(
+            annotationElement.asType(), "create" + annotationElement.getSimpleName());
+
+    createMethod.annotate(AutoAnnotation.class);
+    createMethod.addModifiers(PUBLIC, STATIC);
+
+    ImmutableList.Builder<Snippet> parameters = ImmutableList.builder();
+    for (ExecutableElement annotationMember : methodsIn(annotationElement.getEnclosedElements())) {
+      String parameterName = annotationMember.getSimpleName().toString();
+      TypeName parameterType = TypeNames.forTypeMirror(annotationMember.getReturnType());
+      createMethod.addParameter(parameterType, parameterName);
+      parameters.add(Snippet.format("%s", parameterName));
+    }
+
+    ClassName autoAnnotationClass = mapKeyCreatorWriter.name().peerNamed(
+        "AutoAnnotation_" + mapKeyCreatorWriter.name().simpleName() + "_" + createMethod.name());
+    createMethod.body().addSnippet(
+        "return new %s(%s);", autoAnnotationClass, makeParametersSnippet(parameters.build()));
+  }
+
+  private static Set<TypeElement> nestedAnnotationElements(TypeElement annotationElement) {
+    return nestedAnnotationElements(annotationElement, new LinkedHashSet<TypeElement>());
+  }
+
+  private static Set<TypeElement> nestedAnnotationElements(
+      TypeElement annotationElement, Set<TypeElement> annotationElements) {
+    if (annotationElements.add(annotationElement)) {
+      for (ExecutableElement method : methodsIn(annotationElement.getEnclosedElements())) {
+        TRAVERSE_NESTED_ANNOTATIONS.visit(method.getReturnType(), annotationElements);
+      }
+    }
+    return annotationElements;
+  }
+
+  private static final SimpleTypeVisitor6<Void, Set<TypeElement>> TRAVERSE_NESTED_ANNOTATIONS =
+      new SimpleTypeVisitor6<Void, Set<TypeElement>>() {
+        @Override
+        public Void visitDeclared(DeclaredType t, Set<TypeElement> p) {
+          TypeElement typeElement = MoreTypes.asTypeElement(t);
+          if (typeElement.getKind() == ElementKind.ANNOTATION_TYPE) {
+            nestedAnnotationElements(typeElement, p);
+          }
+          return null;
+        }
+      };
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MapKeyProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/MapKeyProcessingStep.java
new file mode 100644
index 0000000..c4a264a
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MapKeyProcessingStep.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor;
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import dagger.MapKey;
+import dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.util.Types;
+
+import static dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification.unwrappedMapKeyWithAnnotationValue;
+import static dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification.wrappedMapKey;
+import static dagger.internal.codegen.MapKeys.getUnwrappedMapKeyType;
+
+/**
+ * The annotation processor responsible for validating the mapKey annotation and auto-generate
+ * implementation of annotations marked with &#064MapKey where necessary.
+ *
+ * @author Chenying Hou
+ * @since 2.0
+ */
+public class MapKeyProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
+  private final Messager messager;
+  private final Types types;
+  private final MapKeyValidator mapKeyValidator;
+  private final MapKeyGenerator mapKeyGenerator;
+
+  MapKeyProcessingStep(
+      Messager messager,
+      Types types,
+      MapKeyValidator mapKeyValidator,
+      MapKeyGenerator mapKeyGenerator) {
+    this.messager = messager;
+    this.types = types;
+    this.mapKeyValidator = mapKeyValidator;
+    this.mapKeyGenerator = mapKeyGenerator;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.<Class<? extends Annotation>>of(MapKey.class);
+  }
+
+  @Override
+  public Set<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    for (Element element : elementsByAnnotation.get(MapKey.class)) {
+      ValidationReport<Element> mapKeyReport = mapKeyValidator.validate(element);
+      mapKeyReport.printMessagesTo(messager);
+
+      if (mapKeyReport.isClean()) {
+        MapKey mapkey = element.getAnnotation(MapKey.class);
+        if (mapkey.unwrapValue()) {
+          DeclaredType keyType =
+              getUnwrappedMapKeyType(MoreTypes.asDeclared(element.asType()), types);
+          if (keyType.asElement().getKind() == ElementKind.ANNOTATION_TYPE) {
+            writeCreatorClass(
+                unwrappedMapKeyWithAnnotationValue(
+                    MoreElements.asType(element), MoreTypes.asTypeElement(keyType)));
+          }
+        } else {
+          writeCreatorClass(wrappedMapKey(MoreElements.asType(element)));
+        }
+      }
+    }
+    return ImmutableSet.of();
+  }
+
+  private void writeCreatorClass(MapKeyCreatorSpecification mapKeyCreatorType) {
+    try {
+      mapKeyGenerator.generate(mapKeyCreatorType);
+    } catch (SourceFileGenerationException e) {
+      e.printMessageTo(messager);
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MapKeyValidator.java b/compiler/src/main/java/dagger/internal/codegen/MapKeyValidator.java
new file mode 100644
index 0000000..586a1e9
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MapKeyValidator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 dagger.MapKey;
+import java.util.List;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+
+import static dagger.internal.codegen.ErrorMessages.MAPKEY_WITHOUT_MEMBERS;
+import static dagger.internal.codegen.ErrorMessages.UNWRAPPED_MAP_KEY_WITH_ARRAY_MEMBER;
+import static dagger.internal.codegen.ErrorMessages.UNWRAPPED_MAP_KEY_WITH_TOO_MANY_MEMBERS;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+/**
+ * A validator for {@link MapKey} annotations.
+ *
+ * @author Chenying Hou
+ * @since 2.0
+ */
+// TODO(dpb,gak): Should unwrapped MapKeys be required to have their single member be named "value"?
+final class MapKeyValidator {
+  ValidationReport<Element> validate(Element element) {
+    ValidationReport.Builder<Element> builder = ValidationReport.about(element);
+    List<ExecutableElement> members = methodsIn(((TypeElement) element).getEnclosedElements());
+    if (members.isEmpty()) {
+      builder.addError(MAPKEY_WITHOUT_MEMBERS, element);
+    } else if (element.getAnnotation(MapKey.class).unwrapValue()) {
+      if (members.size() > 1) {
+        builder.addError(UNWRAPPED_MAP_KEY_WITH_TOO_MANY_MEMBERS, element);
+      } else if (members.get(0).getReturnType().getKind() == TypeKind.ARRAY) {
+        builder.addError(UNWRAPPED_MAP_KEY_WITH_ARRAY_MEMBER, element);
+      }
+    }
+    return builder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MapKeys.java b/compiler/src/main/java/dagger/internal/codegen/MapKeys.java
new file mode 100644
index 0000000..fbbd8cf
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MapKeys.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import dagger.MapKey;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+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.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor6;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
+import static com.google.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+/**
+ * Methods for extracting {@link MapKey} annotations and key snippets from binding elements.
+ */
+final class MapKeys {
+
+  /**
+   * If {@code bindingElement} is annotated with a {@link MapKey} annotation, returns it.
+   *
+   * @throws IllegalArgumentException if the element is annotated with more than one {@code MapKey}
+   *     annotation
+   */
+  static Optional<? extends AnnotationMirror> getMapKey(Element bindingElement) {
+    ImmutableSet<? extends AnnotationMirror> mapKeys = getMapKeys(bindingElement);
+    return mapKeys.isEmpty()
+        ? Optional.<AnnotationMirror>absent()
+        : Optional.of(getOnlyElement(mapKeys));
+  }
+
+  /**
+   * Returns all of the {@link MapKey} annotations that annotate {@code bindingElement}.
+   */
+  static ImmutableSet<? extends AnnotationMirror> getMapKeys(Element bindingElement) {
+    return getAnnotatedAnnotations(bindingElement, MapKey.class);
+  }
+
+  /**
+   * Returns the annotation value if {@code mapKey}'s type is annotated with
+   * {@link MapKey @MapKey(unwrapValue = true)}.
+   *
+   * @throws IllegalArgumentException if {@code mapKey}'s type is not annotated with
+   *     {@link MapKey @MapKey} at all.
+   */
+  static Optional<? extends AnnotationValue> unwrapValue(AnnotationMirror mapKey) {
+    MapKey mapKeyAnnotation = mapKey.getAnnotationType().asElement().getAnnotation(MapKey.class);
+    checkArgument(
+        mapKeyAnnotation != null, "%s is not annotated with @MapKey", mapKey.getAnnotationType());
+    return mapKeyAnnotation.unwrapValue()
+        ? Optional.of(getOnlyElement(mapKey.getElementValues().values()))
+        : Optional.<AnnotationValue>absent();
+  }
+
+  /**
+   * Returns the map key type for an unwrapped {@link MapKey} annotation type. If the single member
+   * type is primitive, returns the boxed type.
+   *
+   * @throws IllegalArgumentException if {@code mapKeyAnnotationType} is not an annotation type or
+   *     has more than one member, or if its single member is an array
+   * @throws NoSuchElementException if the annotation has no members
+   */
+  public static DeclaredType getUnwrappedMapKeyType(
+      final DeclaredType mapKeyAnnotationType, final Types types) {
+    checkArgument(
+        MoreTypes.asTypeElement(mapKeyAnnotationType).getKind() == ElementKind.ANNOTATION_TYPE,
+        "%s is not an annotation type",
+        mapKeyAnnotationType);
+
+    final ExecutableElement onlyElement =
+        getOnlyElement(methodsIn(mapKeyAnnotationType.asElement().getEnclosedElements()));
+
+    SimpleTypeVisitor6<DeclaredType, Void> keyTypeElementVisitor =
+        new SimpleTypeVisitor6<DeclaredType, Void>() {
+
+          @Override
+          public DeclaredType visitArray(ArrayType t, Void p) {
+            throw new IllegalArgumentException(
+                mapKeyAnnotationType + "." + onlyElement.getSimpleName() + " cannot be an array");
+          }
+
+          @Override
+          public DeclaredType visitPrimitive(PrimitiveType t, Void p) {
+            return MoreTypes.asDeclared(types.boxedClass(t).asType());
+          }
+
+          @Override
+          public DeclaredType visitDeclared(DeclaredType t, Void p) {
+            return t;
+          }
+        };
+    return keyTypeElementVisitor.visit(onlyElement.getReturnType());
+  }
+
+  /**
+   * Returns the name of the generated class that contains the static {@code create} methods for a
+   * {@link MapKey} annotation type.
+   */
+  public static ClassName getMapKeyCreatorClassName(TypeElement mapKeyType) {
+    ClassName mapKeyTypeName = ClassName.fromTypeElement(mapKeyType);
+    return mapKeyTypeName.topLevelClassName().peerNamed(mapKeyTypeName.classFileName() + "Creator");
+  }
+
+  /**
+   * Returns a snippet for the map key specified by the {@link MapKey} annotation on
+   * {@code bindingElement}.
+   *
+   * @throws IllegalArgumentException if the element is annotated with more than one {@code MapKey}
+   *     annotation
+   * @throws IllegalStateException if {@code bindingElement} is not annotated with a {@code MapKey}
+   *     annotation
+   */
+  static Snippet getMapKeySnippet(Element bindingElement) {
+    AnnotationMirror mapKey = getMapKey(bindingElement).get();
+    ClassName mapKeyCreator =
+        getMapKeyCreatorClassName(MoreTypes.asTypeElement(mapKey.getAnnotationType()));
+    Optional<? extends AnnotationValue> unwrappedValue = unwrapValue(mapKey);
+    if (unwrappedValue.isPresent()) {
+      return new MapKeySnippetExceptArrays(mapKeyCreator)
+          .visit(unwrappedValue.get(), unwrappedValue.get());
+    } else {
+      return annotationSnippet(mapKey, new MapKeySnippet(mapKeyCreator));
+    }
+  }
+
+  /**
+   * Returns a snippet to create the visited value in code. Expects its parameter to be a class with
+   * static creation methods for all nested annotation types.
+   *
+   * <p>Note that {@link AnnotationValue#toString()} is the source-code representation of the value
+   * <em>when used in an annotation</em>, which is not always the same as the representation needed
+   * when creating the value in a method body.
+   *
+   * <p>For example, inside an annotation, a nested array of {@code int}s is simply
+   * <code>{1, 2, 3}</code>, but in code it would have to be <code> new int[] {1, 2, 3}</code>.
+   */
+  private static class MapKeySnippet
+      extends SimpleAnnotationValueVisitor6<Snippet, AnnotationValue> {
+
+    final ClassName mapKeyCreator;
+
+    MapKeySnippet(ClassName mapKeyCreator) {
+      this.mapKeyCreator = mapKeyCreator;
+    }
+
+    @Override
+    public Snippet visitEnumConstant(VariableElement c, AnnotationValue p) {
+      return Snippet.format(
+          "%s.%s", TypeNames.forTypeMirror(c.getEnclosingElement().asType()), c.getSimpleName());
+    }
+
+    @Override
+    public Snippet visitAnnotation(AnnotationMirror a, AnnotationValue p) {
+      return annotationSnippet(a, this);
+    }
+
+    @Override
+    public Snippet visitType(TypeMirror t, AnnotationValue p) {
+      return Snippet.format("%s.class", TypeNames.forTypeMirror(t));
+    }
+
+    @Override
+    public Snippet visitString(String s, AnnotationValue p) {
+      return Snippet.format("%s", p);
+    }
+
+    @Override
+    public Snippet visitByte(byte b, AnnotationValue p) {
+      return Snippet.format("(byte) %s", b);
+    }
+
+    @Override
+    public Snippet visitChar(char c, AnnotationValue p) {
+      return Snippet.format("%s", p);
+    }
+
+    @Override
+    public Snippet visitDouble(double d, AnnotationValue p) {
+      return Snippet.format("%sD", d);
+    }
+
+    @Override
+    public Snippet visitFloat(float f, AnnotationValue p) {
+      return Snippet.format("%sF", f);
+    }
+
+    @Override
+    public Snippet visitInt(int i, AnnotationValue p) {
+      return Snippet.format("(int) %s", i);
+    }
+
+    @Override
+    public Snippet visitLong(long i, AnnotationValue p) {
+      return Snippet.format("%sL", i);
+    }
+
+    @Override
+    public Snippet visitShort(short s, AnnotationValue p) {
+      return Snippet.format("(short) %s", s);
+    }
+
+    @Override
+    protected Snippet defaultAction(Object o, AnnotationValue p) {
+      return Snippet.format("%s", o);
+    }
+
+    @Override
+    public Snippet visitArray(List<? extends AnnotationValue> values, AnnotationValue p) {
+      ImmutableList.Builder<Snippet> snippets = ImmutableList.builder();
+      for (int i = 0; i < values.size(); i++) {
+        snippets.add(this.visit(values.get(i), p));
+      }
+      return Snippet.format("{%s}", makeParametersSnippet(snippets.build()));
+    }
+  }
+
+  /**
+   * Returns a snippet for the visited value. Expects its parameter to be a class with static
+   * creation methods for all nested annotation types.
+   *
+   * <p>Throws {@link IllegalArgumentException} if the visited value is an array.
+   */
+  private static class MapKeySnippetExceptArrays extends MapKeySnippet {
+
+    MapKeySnippetExceptArrays(ClassName mapKeyCreator) {
+      super(mapKeyCreator);
+    }
+
+    @Override
+    public Snippet visitArray(List<? extends AnnotationValue> values, AnnotationValue p) {
+      throw new IllegalArgumentException("Cannot unwrap arrays");
+    }
+  }
+
+  /**
+   * Returns a snippet that calls a static method on {@code mapKeySnippet.mapKeyCreator} to create
+   * an annotation from {@code mapKeyAnnotation}.
+   */
+  private static Snippet annotationSnippet(
+      AnnotationMirror mapKeyAnnotation, final MapKeySnippet mapKeySnippet) {
+    return Snippet.format(
+        "%s.create%s(%s)",
+        mapKeySnippet.mapKeyCreator,
+        mapKeyAnnotation.getAnnotationType().asElement().getSimpleName(),
+        makeParametersSnippet(
+            transform(
+                getAnnotationValuesWithDefaults(mapKeyAnnotation).entrySet(),
+                new Function<Map.Entry<ExecutableElement, AnnotationValue>, Snippet>() {
+                  @Override
+                  public Snippet apply(Map.Entry<ExecutableElement, AnnotationValue> entry) {
+                    return ARRAY_LITERAL_PREFIX.visit(
+                        entry.getKey().getReturnType(),
+                        mapKeySnippet.visit(entry.getValue(), entry.getValue()));
+                  }
+                })));
+  }
+
+  /**
+   * If the visited type is an array, prefixes the parameter snippet with {@code new T[]}, where
+   * {@code T} is the raw array component type.
+   */
+  private static final SimpleTypeVisitor6<Snippet, Snippet> ARRAY_LITERAL_PREFIX =
+      new SimpleTypeVisitor6<Snippet, Snippet>() {
+
+        @Override
+        public Snippet visitArray(ArrayType t, Snippet p) {
+          return Snippet.format("new %s[] %s", RAW_TYPE_NAME.visit(t.getComponentType()), p);
+        }
+
+        @Override
+        protected Snippet defaultAction(TypeMirror e, Snippet p) {
+          return p;
+        }
+      };
+
+  /**
+   * If the visited type is an array, returns the name of its raw component type; otherwise returns
+   * the name of the type itself.
+   */
+  private static final SimpleTypeVisitor6<TypeName, Void> RAW_TYPE_NAME =
+      new SimpleTypeVisitor6<TypeName, Void>() {
+        @Override
+        public TypeName visitDeclared(DeclaredType t, Void p) {
+          return ClassName.fromTypeElement(MoreTypes.asTypeElement(t));
+        }
+
+        @Override
+        protected TypeName defaultAction(TypeMirror e, Void p) {
+          return TypeNames.forTypeMirror(e);
+        }
+      };
+
+  private MapKeys() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MembersInjectionBinding.java b/compiler/src/main/java/dagger/internal/codegen/MembersInjectionBinding.java
new file mode 100644
index 0000000..7fbcf11
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MembersInjectionBinding.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.SetMultimap;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementKindVisitor6;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+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 javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * Represents the full members injection of a particular type. This does not pay attention to
+ * injected members on supertypes.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@AutoValue
+abstract class MembersInjectionBinding extends Binding {
+  @Override abstract TypeElement bindingElement();
+        
+  /** The set of individual sites where {@link Inject} is applied. */
+  abstract ImmutableSortedSet<InjectionSite> injectionSites();
+
+  abstract Optional<DependencyRequest> parentInjectorRequest();
+
+  enum Strategy {
+    NO_OP,
+    INJECT_MEMBERS,
+  }
+
+  Strategy injectionStrategy() {
+    return injectionSites().isEmpty() ? Strategy.NO_OP : Strategy.INJECT_MEMBERS;
+  }
+
+  MembersInjectionBinding withoutParentInjectorRequest() {
+    return new AutoValue_MembersInjectionBinding(
+          key(),
+          dependencies(),
+          implicitDependencies(),
+          bindingPackage(),
+          hasNonDefaultTypeParameters(),
+          bindingElement(),
+          injectionSites(),
+          Optional.<DependencyRequest>absent());
+  }
+
+  @Override
+  protected Binding.Type bindingType() {
+    return Binding.Type.MEMBERS_INJECTION;
+  }
+
+  @AutoValue
+  abstract static class InjectionSite {
+    enum Kind {
+      FIELD,
+      METHOD,
+    }
+
+    abstract Kind kind();
+
+    abstract Element element();
+
+    abstract ImmutableSet<DependencyRequest> dependencies();
+    
+    protected int indexAmongSiblingMembers(InjectionSite injectionSite) {
+      return injectionSite
+          .element()
+          .getEnclosingElement()
+          .getEnclosedElements()
+          .indexOf(injectionSite.element());
+    }
+  }
+
+  static final class Factory {
+    private final Elements elements;
+    private final Types types;
+    private final Key.Factory keyFactory;
+    private final DependencyRequest.Factory dependencyRequestFactory;
+
+    Factory(Elements elements, Types types, Key.Factory keyFactory,
+        DependencyRequest.Factory dependencyRequestFactory) {
+      this.elements = checkNotNull(elements);
+      this.types = checkNotNull(types);
+      this.keyFactory = checkNotNull(keyFactory);
+      this.dependencyRequestFactory = checkNotNull(dependencyRequestFactory);
+    }
+
+    private InjectionSite injectionSiteForInjectMethod(
+        ExecutableElement methodElement, DeclaredType containingType) {
+      checkNotNull(methodElement);
+      checkArgument(methodElement.getKind().equals(ElementKind.METHOD));
+      ExecutableType resolved =
+          MoreTypes.asExecutable(types.asMemberOf(containingType, methodElement));
+      return new AutoValue_MembersInjectionBinding_InjectionSite(
+          InjectionSite.Kind.METHOD,
+          methodElement,
+          dependencyRequestFactory.forRequiredResolvedVariables(
+              containingType, methodElement.getParameters(), resolved.getParameterTypes()));
+    }
+
+    private InjectionSite injectionSiteForInjectField(
+        VariableElement fieldElement, DeclaredType containingType) {
+      checkNotNull(fieldElement);
+      checkArgument(fieldElement.getKind().equals(ElementKind.FIELD));
+      checkArgument(isAnnotationPresent(fieldElement, Inject.class));
+      TypeMirror resolved = types.asMemberOf(containingType, fieldElement);
+      return new AutoValue_MembersInjectionBinding_InjectionSite(
+          InjectionSite.Kind.FIELD,
+          fieldElement,
+          ImmutableSet.of(
+              dependencyRequestFactory.forRequiredResolvedVariable(
+                  containingType, fieldElement, resolved)));
+    }
+
+    /** Returns an unresolved version of this binding. */
+    MembersInjectionBinding unresolve(MembersInjectionBinding binding) {
+      checkState(binding.hasNonDefaultTypeParameters());
+      DeclaredType unresolved = MoreTypes.asDeclared(binding.bindingElement().asType());
+      return forInjectedType(unresolved, Optional.<TypeMirror>absent());
+    }
+
+    /** Returns true if the type has some injected members in itself or any of its super classes. */
+    boolean hasInjectedMembers(DeclaredType declaredType) {
+      return !getInjectionSites(declaredType).isEmpty();
+    }
+
+    /**
+     * Returns a MembersInjectionBinding for the given type. If {@code resolvedType} is present,
+     * this will return a resolved binding, with the key & type resolved to the given type (using
+     * {@link Types#asMemberOf(DeclaredType, Element)}).
+     */
+    MembersInjectionBinding forInjectedType(
+        DeclaredType declaredType, Optional<TypeMirror> resolvedType) {
+      // If the class this is injecting has some type arguments, resolve everything.
+      if (!declaredType.getTypeArguments().isEmpty() && resolvedType.isPresent()) {
+        DeclaredType resolved = MoreTypes.asDeclared(resolvedType.get());
+        // Validate that we're resolving from the correct type.
+        checkState(
+            types.isSameType(types.erasure(resolved), types.erasure(declaredType)),
+            "erased expected type: %s, erased actual type: %s",
+            types.erasure(resolved),
+            types.erasure(declaredType));
+        declaredType = resolved;
+      }
+      ImmutableSortedSet<InjectionSite> injectionSites = getInjectionSites(declaredType);
+      ImmutableSet<DependencyRequest> dependencies =
+          FluentIterable.from(injectionSites)
+              .transformAndConcat(
+                  new Function<InjectionSite, Set<DependencyRequest>>() {
+                    @Override
+                    public Set<DependencyRequest> apply(InjectionSite input) {
+                      return input.dependencies();
+                    }
+                  })
+              .toSet();
+
+      Optional<DependencyRequest> parentInjectorRequest =
+          MoreTypes.nonObjectSuperclass(types, elements, declaredType)
+              .transform(
+                  new Function<DeclaredType, DependencyRequest>() {
+                    @Override
+                    public DependencyRequest apply(DeclaredType input) {
+                      return dependencyRequestFactory.forMembersInjectedType(input);
+                    }
+                  });
+
+      Key key = keyFactory.forMembersInjectedType(declaredType);
+      TypeElement typeElement = MoreElements.asType(declaredType.asElement());
+      return new AutoValue_MembersInjectionBinding(
+          key,
+          dependencies,
+          dependencies,
+          findBindingPackage(key),
+          hasNonDefaultTypeParameters(typeElement, key.type(), types),
+          typeElement,
+          injectionSites,
+          parentInjectorRequest);
+    }
+
+    private ImmutableSortedSet<InjectionSite> getInjectionSites(DeclaredType declaredType) {
+      Set<InjectionSite> injectionSites = new HashSet<>();
+      final List<TypeElement> ancestors = new ArrayList<>();
+      SetMultimap<String, ExecutableElement> overriddenMethodMap = LinkedHashMultimap.create();
+      for (Optional<DeclaredType> currentType = Optional.of(declaredType);
+          currentType.isPresent();
+          currentType = MoreTypes.nonObjectSuperclass(types, elements, currentType.get())) {
+        final DeclaredType type = currentType.get();
+        ancestors.add(MoreElements.asType(type.asElement()));
+        for (Element enclosedElement : type.asElement().getEnclosedElements()) {
+          Optional<InjectionSite> maybeInjectionSite =
+              injectionSiteVisitor.visit(enclosedElement, type);
+          if (maybeInjectionSite.isPresent()) {
+            InjectionSite injectionSite = maybeInjectionSite.get();
+            if (shouldBeInjected(injectionSite.element(), overriddenMethodMap)) {
+              injectionSites.add(injectionSite);
+            }
+            if (injectionSite.kind() == InjectionSite.Kind.METHOD) {
+              ExecutableElement injectionSiteMethod =
+                  MoreElements.asExecutable(injectionSite.element());
+              overriddenMethodMap.put(
+                  injectionSiteMethod.getSimpleName().toString(), injectionSiteMethod);
+            }
+          }
+        }
+      }
+      return ImmutableSortedSet.copyOf(
+          new Comparator<InjectionSite>() {
+            @Override
+            public int compare(InjectionSite left, InjectionSite right) {
+              return ComparisonChain.start()
+                  // supertypes before subtypes
+                  .compare(
+                      ancestors.indexOf(right.element().getEnclosingElement()),
+                      ancestors.indexOf(left.element().getEnclosingElement()))
+                  // fields before methods
+                  .compare(left.element().getKind(), right.element().getKind())
+                  // then sort by whichever element comes first in the parent
+                  // this isn't necessary, but makes the processor nice and predictable
+                  .compare(
+                      left.indexAmongSiblingMembers(left), right.indexAmongSiblingMembers(right))
+                  .result();
+            }
+          },
+          injectionSites);
+    }
+
+    private boolean shouldBeInjected(
+        Element injectionSite, SetMultimap<String, ExecutableElement> overriddenMethodMap) {
+      if (!isAnnotationPresent(injectionSite, Inject.class)
+          || injectionSite.getModifiers().contains(PRIVATE)
+          || injectionSite.getModifiers().contains(STATIC)) {
+        return false;
+      }
+
+      if (injectionSite.getKind().isField()) { // Inject all fields (self and ancestors)
+        return true;
+      }
+
+      // For each method with the same name belonging to any descendant class, return false if any
+      // method has already overridden the injectionSite method. To decrease the number of methods
+      // that are checked, we store the already injected methods in a SetMultimap and only
+      // check the methods with the same name.
+      ExecutableElement injectionSiteMethod = MoreElements.asExecutable(injectionSite);
+      TypeElement injectionSiteType = MoreElements.asType(injectionSite.getEnclosingElement());
+      for (ExecutableElement method :
+          overriddenMethodMap.get(injectionSiteMethod.getSimpleName().toString())) {
+        if (elements.overrides(method, injectionSiteMethod, injectionSiteType)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    private final ElementVisitor<Optional<InjectionSite>, DeclaredType> injectionSiteVisitor =
+        new ElementKindVisitor6<Optional<InjectionSite>, DeclaredType>(
+            Optional.<InjectionSite>absent()) {
+          @Override
+          public Optional<InjectionSite> visitExecutableAsMethod(
+              ExecutableElement e, DeclaredType type) {
+            return Optional.of(injectionSiteForInjectMethod(e, type));
+          }
+
+          @Override
+          public Optional<InjectionSite> visitVariableAsField(
+              VariableElement e, DeclaredType type) {
+            return (isAnnotationPresent(e, Inject.class)
+                    && !e.getModifiers().contains(PRIVATE)
+                    && !e.getModifiers().contains(STATIC))
+                ? Optional.of(injectionSiteForInjectField(e, type))
+                : Optional.<InjectionSite>absent();
+          }
+        };
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MembersInjectorGenerator.java b/compiler/src/main/java/dagger/internal/codegen/MembersInjectorGenerator.java
new file mode 100644
index 0000000..3694d2e
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MembersInjectorGenerator.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import dagger.MembersInjector;
+import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.ConstructorWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.Modifiable;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import dagger.internal.codegen.writer.TypeVariableName;
+import dagger.internal.codegen.writer.VariableWriter;
+import dagger.internal.codegen.writer.VoidName;
+import dagger.producers.Producer;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.annotation.Generated;
+import javax.annotation.processing.Filer;
+import javax.inject.Provider;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.util.SimpleTypeVisitor7;
+
+import static com.google.auto.common.MoreElements.getPackage;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static dagger.internal.codegen.SourceFiles.frameworkTypeUsageStatement;
+import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
+import static dagger.internal.codegen.SourceFiles.parameterizedGeneratedTypeNameForBinding;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+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;
+
+/**
+ * Generates {@link MembersInjector} implementations from {@link MembersInjectionBinding} instances.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class MembersInjectorGenerator extends SourceFileGenerator<MembersInjectionBinding> {
+  private final DependencyRequestMapper dependencyRequestMapper;
+
+  MembersInjectorGenerator(
+      Filer filer,
+      DependencyRequestMapper dependencyRequestMapper) {
+    super(filer);
+    this.dependencyRequestMapper = dependencyRequestMapper;
+  }
+
+  @Override
+  ClassName nameGeneratedType(MembersInjectionBinding binding) {
+    return membersInjectorNameForType(binding.bindingElement());
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(
+      MembersInjectionBinding binding) {
+    return FluentIterable.from(binding.injectionSites())
+        .transform(new Function<InjectionSite, Element>() {
+          @Override public Element apply(InjectionSite injectionSite) {
+            return injectionSite.element();
+          }
+        })
+        .toSet();
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(MembersInjectionBinding binding) {
+    return Optional.of(binding.bindingElement());
+  }
+  
+  @Override
+  ImmutableSet<JavaWriter> write(ClassName generatedTypeName, MembersInjectionBinding binding) {
+    // Empty members injection bindings are special and don't need source files.
+    if (binding.injectionSites().isEmpty()) {
+      return ImmutableSet.of();
+    }
+    Set<String> delegateMethods = new HashSet<>();
+
+    // We don't want to write out resolved bindings -- we want to write out the generic version.
+    checkState(!binding.hasNonDefaultTypeParameters()); 
+
+    TypeName injectedTypeName = TypeNames.forTypeMirror(binding.key().type());
+    JavaWriter writer = JavaWriter.inPackage(generatedTypeName.packageName());
+
+    ClassWriter injectorWriter = writer.addClass(generatedTypeName.simpleName());
+    List<TypeVariableName> typeParameters = Lists.newArrayList();
+    for (TypeParameterElement typeParameter : binding.bindingTypeElement().getTypeParameters()) {
+      typeParameters.add(TypeVariableName.fromTypeParameterElement(typeParameter));
+    }
+    injectorWriter.addTypeParameters(typeParameters);
+    injectorWriter.annotate(Generated.class)
+        .setValue(ComponentProcessor.class.getCanonicalName());
+    injectorWriter.addModifiers(PUBLIC, FINAL);
+    TypeName implementedType =
+        ParameterizedTypeName.create(MembersInjector.class, injectedTypeName);
+    injectorWriter.addImplementedType(implementedType);
+
+    ConstructorWriter constructorWriter = injectorWriter.addConstructor();
+    constructorWriter.addModifiers(PUBLIC);
+    MethodWriter injectMembersWriter = injectorWriter.addMethod(VoidName.VOID, "injectMembers");
+    injectMembersWriter.addModifiers(PUBLIC);
+    injectMembersWriter.annotate(Override.class);
+    injectMembersWriter.addParameter(injectedTypeName, "instance");
+    injectMembersWriter.body().addSnippet(Joiner.on('\n').join(
+        "if (instance == null) {",
+        "  throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "}"));
+
+    ImmutableMap<BindingKey, FrameworkField> fields =
+        SourceFiles.generateBindingFieldsForDependencies(
+            dependencyRequestMapper, ImmutableSet.copyOf(binding.dependencies()));
+
+    ImmutableMap.Builder<BindingKey, FieldWriter> dependencyFieldsBuilder =
+        ImmutableMap.builder();
+    
+    // We use a static create method so that generated components can avoid having
+    // to refer to the generic types of the factory.
+    // (Otherwise they may have visibility problems referring to the types.)
+    MethodWriter createMethodWriter = injectorWriter.addMethod(implementedType, "create");
+    createMethodWriter.addTypeParameters(typeParameters);
+    createMethodWriter.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+    boolean usesRawFrameworkTypes = false;
+    for (Entry<BindingKey, FrameworkField> fieldEntry : fields.entrySet()) {
+      BindingKey bindingKey = fieldEntry.getKey();
+      FrameworkField bindingField = fieldEntry.getValue();
+
+      // If the dependency type is not visible to this members injector, then use the raw framework
+      // type for the field.
+      boolean useRawFrameworkType =
+          !VISIBLE_TO_MEMBERS_INJECTOR.visit(bindingKey.key().type(), binding);
+
+      FieldWriter field =
+          injectorWriter.addField(
+              useRawFrameworkType
+                  ? bindingField.frameworkType().type()
+                  : bindingField.frameworkType(),
+              bindingField.name());
+
+      field.addModifiers(PRIVATE, FINAL);
+      VariableWriter constructorParameter =
+          constructorWriter.addParameter(field.type(), field.name());
+      VariableWriter createMethodParameter =
+          createMethodWriter.addParameter(constructorParameter.type(), constructorParameter.name());
+
+      // If we're using the raw type for the field, then suppress the injectMembers method's
+      // unchecked-type warning and the field's and the constructor and create-method's
+      // parameters' raw-type warnings.
+      if (useRawFrameworkType) {
+        usesRawFrameworkTypes = true;
+        suppressRawTypesWarning(field);
+        suppressRawTypesWarning(constructorParameter);
+        suppressRawTypesWarning(createMethodParameter);
+      }
+
+      constructorWriter.body().addSnippet("assert %s != null;", field.name());
+      constructorWriter.body().addSnippet("this.%1$s = %1$s;", field.name());
+      dependencyFieldsBuilder.put(bindingKey, field);
+    }
+
+    createMethodWriter
+        .body()
+        .addSnippet(
+            "  return new %s(%s);",
+            parameterizedGeneratedTypeNameForBinding(binding),
+            Joiner.on(", ").join(constructorWriter.parameters().keySet()));
+
+    ImmutableMap<BindingKey, FieldWriter> dependencyFields = dependencyFieldsBuilder.build();
+    for (InjectionSite injectionSite : binding.injectionSites()) {
+      injectMembersWriter
+          .body()
+          .addSnippet(
+              visibleToMembersInjector(binding, injectionSite.element())
+                  ? directInjectMemberSnippet(binding, dependencyFields, injectionSite)
+                  : delegateInjectMemberSnippet(dependencyFields, injectionSite));
+      if (!injectionSite.element().getModifiers().contains(PUBLIC)
+          && injectionSite.element().getEnclosingElement().equals(binding.bindingElement())
+          && delegateMethods.add(injectionSiteDelegateMethodName(injectionSite.element()))) {
+        writeInjectorMethodForSubclasses(
+            injectorWriter,
+            dependencyFields,
+            typeParameters,
+            injectedTypeName,
+            injectionSite.element(),
+            injectionSite.dependencies());
+      }
+    }
+    
+    if (usesRawFrameworkTypes) {
+      injectMembersWriter.annotate(SuppressWarnings.class).setValue("unchecked");
+    }
+
+    return ImmutableSet.of(writer);
+  }
+
+  /**
+   * Returns {@code true} if {@code element} is visible to the members injector for {@code binding}.
+   */
+  // TODO(dpb,gak): Make sure that all cases are covered here. E.g., what if element is public but
+  // enclosed in a package-private element?
+  private static boolean visibleToMembersInjector(
+      MembersInjectionBinding binding, Element element) {
+    return getPackage(element).equals(getPackage(binding.bindingElement()))
+        || element.getModifiers().contains(PUBLIC);
+  }
+
+  /**
+   * Returns a snippet that directly injects the instance's field or method.
+   */
+  private Snippet directInjectMemberSnippet(
+      MembersInjectionBinding binding,
+      ImmutableMap<BindingKey, FieldWriter> dependencyFields,
+      InjectionSite injectionSite) {
+    return Snippet.format(
+        injectionSite.element().getKind().isField() ? "%s.%s = %s;" : "%s.%s(%s);",
+        getInstanceSnippetWithPotentialCast(
+            injectionSite.element().getEnclosingElement(), binding.bindingElement()),
+        injectionSite.element().getSimpleName(),
+        makeParametersSnippet(
+            parameterSnippets(dependencyFields, injectionSite.dependencies(), true)));
+  }
+
+  /**
+   * Returns a snippet that injects the instance's field or method by calling a static method on the
+   * parent members injector class.
+   */
+  private Snippet delegateInjectMemberSnippet(
+      ImmutableMap<BindingKey, FieldWriter> dependencyFields, InjectionSite injectionSite) {
+    return Snippet.format(
+        "%s.%s(%s);",
+        membersInjectorNameForType(
+            MoreElements.asType(injectionSite.element().getEnclosingElement())),
+        injectionSiteDelegateMethodName(injectionSite.element()),
+        makeParametersSnippet(
+            new ImmutableList.Builder<Snippet>()
+                .add(Snippet.format("instance"))
+                .addAll(parameterSnippets(dependencyFields, injectionSite.dependencies(), false))
+                .build()));
+  }
+
+  /**
+   * Returns the parameters for injecting a member.
+   *
+   * @param passValue if {@code true}, each parameter snippet will be the result of converting the
+   *     field from the framework type ({@link Provider}, {@link Producer}, etc.) to the real value;
+   *     if {@code false}, each parameter snippet will be just the field
+   */
+  private ImmutableList<Snippet> parameterSnippets(
+      ImmutableMap<BindingKey, FieldWriter> dependencyFields,
+      ImmutableSet<DependencyRequest> dependencies,
+      boolean passValue) {
+    ImmutableList.Builder<Snippet> parameters = ImmutableList.builder();
+    for (DependencyRequest dependency : dependencies) {
+      Snippet fieldSnippet =
+          Snippet.format("%s", dependencyFields.get(dependency.bindingKey()).name());
+      parameters.add(
+          passValue ? frameworkTypeUsageStatement(fieldSnippet, dependency.kind()) : fieldSnippet);
+    }
+    return parameters.build();
+  }
+
+  private Snippet getInstanceSnippetWithPotentialCast(
+      Element injectionSiteElement, Element bindingElement) {
+    return (injectionSiteElement.equals(bindingElement))
+        ? Snippet.format("instance")
+        : Snippet.format("((%s)instance)", injectionSiteElement);
+  }
+
+  private String injectionSiteDelegateMethodName(Element injectionSiteElement) {
+    return "inject"
+        + CaseFormat.LOWER_CAMEL.to(
+            CaseFormat.UPPER_CAMEL, injectionSiteElement.getSimpleName().toString());
+  }
+
+  private void writeInjectorMethodForSubclasses(
+      ClassWriter injectorWriter,
+      ImmutableMap<BindingKey, FieldWriter> dependencyFields,
+      List<TypeVariableName> typeParameters,
+      TypeName injectedTypeName,
+      Element injectionElement,
+      ImmutableSet<DependencyRequest> dependencies) {
+    MethodWriter methodWriter =
+        injectorWriter.addMethod(VoidName.VOID, injectionSiteDelegateMethodName(injectionElement));
+    methodWriter.addModifiers(PUBLIC, STATIC);
+    methodWriter.addParameter(injectedTypeName, "instance");
+    methodWriter.addTypeParameters(typeParameters);
+    ImmutableList.Builder<Snippet> providedParameters = ImmutableList.builder();
+    Set<String> parameterNames = new HashSet<>();
+    for (DependencyRequest dependency : dependencies) {
+      FieldWriter field = dependencyFields.get(dependency.bindingKey());
+      VariableWriter parameter =
+          methodWriter.addParameter(
+              field.type(),
+              staticInjectMethodDependencyParameterName(parameterNames, dependency, field));
+      providedParameters.add(
+          frameworkTypeUsageStatement(Snippet.format("%s", parameter.name()), dependency.kind()));
+    }
+    if (injectionElement.getKind().isField()) {
+      methodWriter
+          .body()
+          .addSnippet(
+              "instance.%s = %s;",
+              injectionElement.getSimpleName(),
+              getOnlyElement(providedParameters.build()));
+    } else {
+      methodWriter
+          .body()
+          .addSnippet(
+              "instance.%s(%s);",
+              injectionElement.getSimpleName(),
+              makeParametersSnippet(providedParameters.build()));
+    }
+  }
+
+  /**
+   * Returns the static inject method parameter name for a dependency.
+   *
+   * @param parameterNames the parameter names used so far
+   * @param dependency the dependency
+   * @param field the field used to hold the framework type for the dependency
+   */
+  private String staticInjectMethodDependencyParameterName(
+      Set<String> parameterNames, DependencyRequest dependency, FieldWriter field) {
+    StringBuilder parameterName =
+        new StringBuilder(dependency.requestElement().getSimpleName().toString());
+    switch (dependency.kind()) {
+      case LAZY:
+      case INSTANCE:
+      case FUTURE:
+        String suffix = ((ParameterizedTypeName) field.type()).type().simpleName();
+        if (parameterName.length() <= suffix.length()
+            || !parameterName.substring(parameterName.length() - suffix.length()).equals(suffix)) {
+          parameterName.append(suffix);
+        }
+        break;
+
+      default:
+        break;
+    }
+    int baseLength = parameterName.length();
+    for (int i = 2; !parameterNames.add(parameterName.toString()); i++) {
+      parameterName.replace(baseLength, parameterName.length(), String.valueOf(i));
+    }
+    return parameterName.toString();
+  }
+
+  private void suppressRawTypesWarning(Modifiable modifiable) {
+    modifiable.annotate(SuppressWarnings.class).setValue("rawtypes");
+  }
+
+  private static final TypeVisitor<Boolean, MembersInjectionBinding> VISIBLE_TO_MEMBERS_INJECTOR =
+      new SimpleTypeVisitor7<Boolean, MembersInjectionBinding>(true) {
+        @Override
+        public Boolean visitArray(ArrayType t, MembersInjectionBinding p) {
+          return visit(t.getComponentType(), p);
+        }
+
+        @Override
+        public Boolean visitDeclared(DeclaredType t, MembersInjectionBinding p) {
+          return visibleToMembersInjector(p, t.asElement());
+        }
+      };
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MethodSignature.java b/compiler/src/main/java/dagger/internal/codegen/MethodSignature.java
new file mode 100644
index 0000000..447ed24
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MethodSignature.java
@@ -0,0 +1,33 @@
+package dagger.internal.codegen;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.collect.ImmutableList;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@AutoValue
+abstract class MethodSignature {
+  abstract String name();
+  abstract ImmutableList<Equivalence.Wrapper<TypeMirror>> parameterTypes();
+  abstract ImmutableList<Equivalence.Wrapper<TypeMirror>> thrownTypes();
+
+  static MethodSignature fromExecutableType(String methodName, ExecutableType methodType) {
+    checkNotNull(methodType);
+    ImmutableList.Builder<Equivalence.Wrapper<TypeMirror>> parameters = ImmutableList.builder();
+    ImmutableList.Builder<Equivalence.Wrapper<TypeMirror>> thrownTypes = ImmutableList.builder();
+    for (TypeMirror parameter : methodType.getParameterTypes()) {
+      parameters.add(MoreTypes.equivalence().wrap(parameter));
+    }
+    for (TypeMirror thrownType : methodType.getThrownTypes()) {
+      thrownTypes.add(MoreTypes.equivalence().wrap(thrownType));
+    }
+    return new AutoValue_MethodSignature(
+        methodName,
+        parameters.build(),
+        thrownTypes.build());
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MethodSignatureFormatter.java b/compiler/src/main/java/dagger/internal/codegen/MethodSignatureFormatter.java
new file mode 100644
index 0000000..078977e
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MethodSignatureFormatter.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Optional;
+import java.util.Iterator;
+import java.util.List;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+import static com.google.common.base.Preconditions.checkState;
+import static dagger.internal.codegen.ErrorMessages.stripCommonTypePrefixes;
+
+/**
+ * Formats the signature of an {@link ExecutableElement} suitable for use in error messages.
+ *
+ * @author Christian Gruber
+ * @since 2.0
+ */
+final class MethodSignatureFormatter extends Formatter<ExecutableElement> {
+  private final Types types;
+
+  MethodSignatureFormatter(Types types) {
+    this.types = types;
+  }
+
+  @Override public String format(ExecutableElement method) {
+    return format(method, Optional.<DeclaredType>absent());
+  }
+
+  /**
+   * Formats an ExecutableElement as if it were contained within the container, if the container is
+   * present.
+   */
+  public String format(ExecutableElement method, Optional<DeclaredType> container) {
+    StringBuilder builder = new StringBuilder();
+    TypeElement type = MoreElements.asType(method.getEnclosingElement());
+    ExecutableType executableType = MoreTypes.asExecutable(method.asType());
+    if (container.isPresent()) {
+      executableType = MoreTypes.asExecutable(types.asMemberOf(container.get(), method));
+      type = MoreElements.asType(container.get().asElement());
+    }
+
+    // TODO(cgruber): AnnotationMirror formatter.
+    List<? extends AnnotationMirror> annotations = method.getAnnotationMirrors();
+    if (!annotations.isEmpty()) {
+      Iterator<? extends AnnotationMirror> annotationIterator = annotations.iterator();
+      for (int i = 0; annotationIterator.hasNext(); i++) {
+        if (i > 0) {
+          builder.append(' ');
+        }
+        builder.append(ErrorMessages.format(annotationIterator.next()));
+      }
+      builder.append(' ');
+    }
+    builder.append(nameOfType(executableType.getReturnType()));
+    builder.append(' ');
+    builder.append(type.getQualifiedName());
+    builder.append('.');
+    builder.append(method.getSimpleName());
+    builder.append('(');
+    checkState(method.getParameters().size() == executableType.getParameterTypes().size());
+    Iterator<? extends VariableElement> parameters = method.getParameters().iterator();
+    Iterator<? extends TypeMirror> parameterTypes = executableType.getParameterTypes().iterator();
+    for (int i = 0; parameters.hasNext(); i++) {
+      if (i > 0) {
+        builder.append(", ");
+      }
+      appendParameter(builder, parameters.next(), parameterTypes.next());
+    }
+    builder.append(')');
+    return builder.toString();
+  }
+
+  private static void appendParameter(StringBuilder builder, VariableElement parameter,
+      TypeMirror type) {
+    Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(parameter);
+    if (qualifier.isPresent()) {
+      builder.append(ErrorMessages.format(qualifier.get())).append(' ');
+    }
+    builder.append(nameOfType(type));
+  }
+
+  private static String nameOfType(TypeMirror type) {
+    if (type.getKind().isPrimitive()) {
+      return MoreTypes.asPrimitiveType(type).toString();
+    } else if (type.getKind() == TypeKind.VOID) {
+      return "void";
+    } else {
+      return stripCommonTypePrefixes(MoreTypes.asDeclared(type).toString());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MissingBindingSuggestions.java b/compiler/src/main/java/dagger/internal/codegen/MissingBindingSuggestions.java
new file mode 100644
index 0000000..4b6f0c3
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MissingBindingSuggestions.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * Utility code that looks for bindings matching a key in all subcomponents in a binding graph so
+ * that a user is advised that a binding exists elsewhere when it is not found in the current
+ * subgraph. If a binding matching a key exists in a sub- or sibling component, that is often what
+ * the user actually wants to use.
+ */
+class MissingBindingSuggestions {
+  /**
+   * Searches the entire binding graph from the top-level graph for a binding matching
+   * {@code key}.
+   */
+  static ImmutableList<String> forKey(BindingGraph topLevelGraph, BindingKey key) {
+    ImmutableList.Builder<String> resolutions = new ImmutableList.Builder<>();
+    Deque<BindingGraph> graphsToTry = new ArrayDeque<>();
+
+    graphsToTry.add(topLevelGraph);
+    do {
+      BindingGraph graph = graphsToTry.removeLast();
+      ResolvedBindings bindings = graph.resolvedBindings().get(key);
+      if ((bindings == null) || bindings.bindings().isEmpty()) {
+        graphsToTry.addAll(graph.subgraphs().values());
+      } else {
+        resolutions.add("A binding with matching key exists in component: "
+            + graph.componentDescriptor().componentDefinitionType().getQualifiedName());
+      }
+    } while (!graphsToTry.isEmpty());
+
+    return resolutions.build();
+  }
+
+  private MissingBindingSuggestions() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ModuleDescriptor.java b/compiler/src/main/java/dagger/internal/codegen/ModuleDescriptor.java
new file mode 100644
index 0000000..c938af2
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ModuleDescriptor.java
@@ -0,0 +1,122 @@
+package dagger.internal.codegen;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import dagger.Module;
+import dagger.Provides;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Verify.verify;
+import static dagger.internal.codegen.ConfigurationAnnotations.getModuleIncludes;
+import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.NONE;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+@AutoValue
+abstract class ModuleDescriptor {
+  static final Function<ModuleDescriptor, TypeElement> getModuleElement() {
+    return new Function<ModuleDescriptor, TypeElement>() {
+      @Override public TypeElement apply(ModuleDescriptor input) {
+        return input.moduleElement();
+      }
+    };
+  }
+
+  abstract AnnotationMirror moduleAnnotation();
+
+  abstract TypeElement moduleElement();
+
+  abstract ImmutableSet<ModuleDescriptor> includedModules();
+
+  abstract ImmutableSet<ContributionBinding> bindings();
+
+  enum DefaultCreationStrategy {
+    PASSED,
+    CONSTRUCTED,
+  }
+
+  abstract DefaultCreationStrategy defaultCreationStrategy();
+
+  static final class Factory {
+    private final Elements elements;
+    private final ProvisionBinding.Factory provisionBindingFactory;
+    private final ProductionBinding.Factory productionBindingFactory;
+
+    Factory(
+        Elements elements,
+        ProvisionBinding.Factory provisionBindingFactory,
+        ProductionBinding.Factory productionBindingFactory) {
+      this.elements = elements;
+      this.provisionBindingFactory = provisionBindingFactory;
+      this.productionBindingFactory = productionBindingFactory;
+    }
+
+    ModuleDescriptor create(TypeElement moduleElement) {
+      AnnotationMirror moduleAnnotation = getModuleAnnotation(moduleElement).get();
+
+      ImmutableSet.Builder<ContributionBinding> bindings = ImmutableSet.builder();
+      for (ExecutableElement moduleMethod : methodsIn(elements.getAllMembers(moduleElement))) {
+        if (isAnnotationPresent(moduleMethod, Provides.class)) {
+          bindings.add(
+              provisionBindingFactory.forProvidesMethod(moduleMethod, moduleElement.asType()));
+        }
+        if (isAnnotationPresent(moduleMethod, Produces.class)) {
+          bindings.add(
+              productionBindingFactory.forProducesMethod(moduleMethod, moduleElement.asType()));
+        }
+      }
+
+      DefaultCreationStrategy defaultCreationStrategy =
+          (componentCanMakeNewInstances(moduleElement)
+              && moduleElement.getTypeParameters().isEmpty())
+                  ? ModuleDescriptor.DefaultCreationStrategy.CONSTRUCTED
+                  : ModuleDescriptor.DefaultCreationStrategy.PASSED;
+
+      return new AutoValue_ModuleDescriptor(
+          moduleAnnotation,
+          moduleElement,
+          ImmutableSet.copyOf(
+              collectIncludedModules(new LinkedHashSet<ModuleDescriptor>(), moduleElement)),
+          bindings.build(),
+          defaultCreationStrategy);
+    }
+
+    private static Optional<AnnotationMirror> getModuleAnnotation(TypeElement moduleElement) {
+      return getAnnotationMirror(moduleElement, Module.class)
+          .or(getAnnotationMirror(moduleElement, ProducerModule.class));
+    }
+
+    private Set<ModuleDescriptor> collectIncludedModules(
+        Set<ModuleDescriptor> includedModules, TypeElement moduleElement) {
+      TypeMirror superclass = moduleElement.getSuperclass();
+      if (!superclass.getKind().equals(NONE)) {
+        verify(superclass.getKind().equals(DECLARED));
+        TypeElement superclassElement = MoreTypes.asTypeElement(superclass);
+        if (!superclassElement.getQualifiedName().contentEquals(Object.class.getCanonicalName())) {
+          collectIncludedModules(includedModules, superclassElement);
+        }
+      }
+      Optional<AnnotationMirror> moduleAnnotation = getModuleAnnotation(moduleElement);
+      if (moduleAnnotation.isPresent()) {
+        for (TypeMirror moduleIncludesType : getModuleIncludes(moduleAnnotation.get())) {
+          includedModules.add(create(MoreTypes.asTypeElement(moduleIncludesType)));
+        }
+      }
+      return includedModules;
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ModuleProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/ModuleProcessingStep.java
new file mode 100644
index 0000000..1afda7d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ModuleProcessingStep.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor;
+import com.google.auto.common.MoreElements;
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import dagger.Module;
+import dagger.Provides;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static javax.lang.model.element.ElementKind.METHOD;
+
+/**
+ * An annotation processor for generating Dagger implementation code based on the {@link Module}
+ * (and {@link Provides}) annotation.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class ModuleProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
+  private final Messager messager;
+  private final ModuleValidator moduleValidator;
+  private final ProvidesMethodValidator providesMethodValidator;
+  private final ProvisionBinding.Factory provisionBindingFactory;
+  private final FactoryGenerator factoryGenerator;
+  private final Set<Element> processedModuleElements = Sets.newLinkedHashSet();
+
+  ModuleProcessingStep(
+      Messager messager,
+      ModuleValidator moduleValidator,
+      ProvidesMethodValidator providesMethodValidator,
+      ProvisionBinding.Factory provisionBindingFactory,
+      FactoryGenerator factoryGenerator) {
+    this.messager = messager;
+    this.moduleValidator = moduleValidator;
+    this.providesMethodValidator = providesMethodValidator;
+    this.provisionBindingFactory = provisionBindingFactory;
+    this.factoryGenerator = factoryGenerator;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.of(Module.class, Provides.class);
+  }
+
+  @Override
+  public Set<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    // first, check and collect all provides methods
+    ImmutableSet.Builder<ExecutableElement> validProvidesMethodsBuilder = ImmutableSet.builder();
+    for (Element providesElement : elementsByAnnotation.get(Provides.class)) {
+      if (providesElement.getKind().equals(METHOD)) {
+        ExecutableElement providesMethodElement = (ExecutableElement) providesElement;
+        ValidationReport<ExecutableElement> methodReport =
+            providesMethodValidator.validate(providesMethodElement);
+        methodReport.printMessagesTo(messager);
+        if (methodReport.isClean()) {
+          validProvidesMethodsBuilder.add(providesMethodElement);
+        }
+      }
+    }
+    ImmutableSet<ExecutableElement> validProvidesMethods = validProvidesMethodsBuilder.build();
+
+    // process each module
+    for (Element moduleElement :
+        Sets.difference(elementsByAnnotation.get(Module.class), processedModuleElements)) {
+      ValidationReport<TypeElement> report =
+          moduleValidator.validate(MoreElements.asType(moduleElement));
+      report.printMessagesTo(messager);
+
+      if (report.isClean()) {
+        ImmutableSet.Builder<ExecutableElement> moduleProvidesMethodsBuilder =
+            ImmutableSet.builder();
+        List<ExecutableElement> moduleMethods =
+            ElementFilter.methodsIn(moduleElement.getEnclosedElements());
+        for (ExecutableElement methodElement : moduleMethods) {
+          if (isAnnotationPresent(methodElement, Provides.class)) {
+            moduleProvidesMethodsBuilder.add(methodElement);
+          }
+        }
+        ImmutableSet<ExecutableElement> moduleProvidesMethods =
+            moduleProvidesMethodsBuilder.build();
+
+        if (Sets.difference(moduleProvidesMethods, validProvidesMethods).isEmpty()) {
+          // all of the provides methods in this module are valid!
+          // time to generate some factories!
+          ImmutableSet<ProvisionBinding> bindings = FluentIterable.from(moduleProvidesMethods)
+              .transform(new Function<ExecutableElement, ProvisionBinding>() {
+                @Override
+                public ProvisionBinding apply(ExecutableElement providesMethod) {
+                  return provisionBindingFactory.forProvidesMethod(providesMethod,
+                      providesMethod.getEnclosingElement().asType());
+                }
+              })
+              .toSet();
+
+          try {
+            for (ProvisionBinding binding : bindings) {
+              factoryGenerator.generate(binding);
+            }
+          } catch (SourceFileGenerationException e) {
+            e.printMessageTo(messager);
+          }
+        }
+      }
+      processedModuleElements.add(moduleElement);
+    }
+    return ImmutableSet.of();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ModuleValidator.java b/compiler/src/main/java/dagger/internal/codegen/ModuleValidator.java
new file mode 100644
index 0000000..8b0c9a2
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ModuleValidator.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.Visibility;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Sets;
+import dagger.Module;
+import dagger.producers.ProducerModule;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+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.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.common.Visibility.PRIVATE;
+import static com.google.auto.common.Visibility.PUBLIC;
+import static com.google.auto.common.Visibility.effectiveVisibilityOfElement;
+import static com.google.common.collect.Iterables.any;
+import static dagger.internal.codegen.ConfigurationAnnotations.getModuleIncludes;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_SAME_NAME;
+import static dagger.internal.codegen.ErrorMessages.METHOD_OVERRIDES_PROVIDES_METHOD;
+import static dagger.internal.codegen.ErrorMessages.MODULES_WITH_TYPE_PARAMS_MUST_BE_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_METHOD_OVERRIDES_ANOTHER;
+import static dagger.internal.codegen.ErrorMessages.REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.REFERENCED_MODULE_MUST_NOT_HAVE_TYPE_PARAMS;
+import static dagger.internal.codegen.ErrorMessages.REFERENCED_MODULE_NOT_ANNOTATED;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Module}s or {@link ProducerModule}s.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class ModuleValidator {
+  private final Types types;
+  private final Elements elements;
+  private final Class<? extends Annotation> moduleClass;
+  private final ImmutableList<Class<? extends Annotation>> includedModuleClasses;
+  private final Class<? extends Annotation> methodClass;
+  private final MethodSignatureFormatter methodSignatureFormatter;
+
+  ModuleValidator(
+      Types types,
+      Elements elements,
+      MethodSignatureFormatter methodSignatureFormatter,
+      Class<? extends Annotation> moduleClass,
+      ImmutableList<Class<? extends Annotation>> includedModuleClasses,
+      Class<? extends Annotation> methodClass) {
+    this.types = types;
+    this.elements = elements;
+    this.moduleClass = moduleClass;
+    this.includedModuleClasses = includedModuleClasses;
+    this.methodClass = methodClass;
+    this.methodSignatureFormatter = methodSignatureFormatter;
+  }
+
+  ValidationReport<TypeElement> validate(final TypeElement subject) {
+    final ValidationReport.Builder<TypeElement> builder = ValidationReport.about(subject);
+
+    List<ExecutableElement> moduleMethods = ElementFilter.methodsIn(subject.getEnclosedElements());
+    ListMultimap<String, ExecutableElement> allMethodsByName = ArrayListMultimap.create();
+    ListMultimap<String, ExecutableElement> bindingMethodsByName = ArrayListMultimap.create();
+    for (ExecutableElement moduleMethod : moduleMethods) {
+      if (isAnnotationPresent(moduleMethod, methodClass)) {
+        bindingMethodsByName.put(moduleMethod.getSimpleName().toString(), moduleMethod);
+      }
+      allMethodsByName.put(moduleMethod.getSimpleName().toString(), moduleMethod);
+    }
+
+    validateModuleVisibility(subject, builder);
+    validateMethodsWithSameName(builder, bindingMethodsByName);
+    if (subject.getKind() != ElementKind.INTERFACE) {
+      validateProvidesOverrides(subject, builder, allMethodsByName, bindingMethodsByName);
+    }
+    validateModifiers(subject, builder);
+    validateReferencedModules(subject, builder);
+
+    // TODO(gak): port the dagger 1 module validation?
+    return builder.build();
+  }
+
+  private void validateModifiers(
+      TypeElement subject, ValidationReport.Builder<TypeElement> builder) {
+    // This coupled with the check for abstract modules in ComponentValidator guarantees that
+    // only modules without type parameters are referenced from @Component(modules={...}).
+    if (!subject.getTypeParameters().isEmpty() && !subject.getModifiers().contains(ABSTRACT)) {
+      builder.addError(MODULES_WITH_TYPE_PARAMS_MUST_BE_ABSTRACT, subject);
+    }
+  }
+
+  private void validateMethodsWithSameName(
+      ValidationReport.Builder<TypeElement> builder,
+      ListMultimap<String, ExecutableElement> bindingMethodsByName) {
+    for (Entry<String, Collection<ExecutableElement>> entry :
+        bindingMethodsByName.asMap().entrySet()) {
+      if (entry.getValue().size() > 1) {
+        for (ExecutableElement offendingMethod : entry.getValue()) {
+          builder.addError(
+              String.format(BINDING_METHOD_WITH_SAME_NAME, methodClass.getSimpleName()),
+              offendingMethod);
+        }
+      }
+    }
+  }
+
+  private void validateReferencedModules(
+      TypeElement subject, ValidationReport.Builder<TypeElement> builder) {
+    // Validate that all the modules we include are valid for inclusion.
+    AnnotationMirror mirror = getAnnotationMirror(subject, moduleClass).get();
+    ImmutableList<TypeMirror> includedTypes = getModuleIncludes(mirror);
+    validateReferencedModules(subject,  builder, includedTypes);
+  }
+
+  /**
+   * Used by {@link ModuleValidator} & {@link ComponentValidator} to validate referenced modules.
+   */
+  void validateReferencedModules(
+      final TypeElement subject,
+      final ValidationReport.Builder<TypeElement> builder,
+      ImmutableList<TypeMirror> includedTypes) {
+    for (TypeMirror includedType : includedTypes) {
+      includedType.accept(
+          new SimpleTypeVisitor6<Void, Void>() {
+            @Override
+            protected Void defaultAction(TypeMirror mirror, Void p) {
+              builder.addError(mirror + " is not a valid module type.", subject);
+              return null;
+            }
+
+            @Override
+            public Void visitDeclared(DeclaredType t, Void p) {
+              final TypeElement element = MoreElements.asType(t.asElement());
+              if (!t.getTypeArguments().isEmpty()) {
+                builder.addError(
+                    String.format(
+                        REFERENCED_MODULE_MUST_NOT_HAVE_TYPE_PARAMS, element.getQualifiedName()),
+                    subject);
+              }
+              boolean isIncludedModule =
+                  any(
+                      includedModuleClasses,
+                      new Predicate<Class<? extends Annotation>>() {
+                        @Override
+                        public boolean apply(Class<? extends Annotation> otherClass) {
+                          return MoreElements.isAnnotationPresent(element, otherClass);
+                        }
+                      });
+              if (!isIncludedModule) {
+                builder.addError(
+                    String.format(
+                        REFERENCED_MODULE_NOT_ANNOTATED,
+                        element.getQualifiedName(),
+                        (includedModuleClasses.size() > 1 ? "one of " : "")
+                            + Joiner.on(", ")
+                                .join(
+                                    FluentIterable.from(includedModuleClasses)
+                                        .transform(
+                                            new Function<Class<? extends Annotation>, String>() {
+                                              @Override
+                                              public String apply(
+                                                  Class<? extends Annotation> otherClass) {
+                                                return "@" + otherClass.getSimpleName();
+                                              }
+                                            }))),
+                    subject);
+              }
+              if (element.getModifiers().contains(ABSTRACT)) {
+                builder.addError(
+                    String.format(
+                        REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT, element.getQualifiedName()),
+                    subject);
+              }
+              return null;
+            }
+          },
+          null);
+    }
+  }
+
+  private void validateProvidesOverrides(
+      TypeElement subject,
+      ValidationReport.Builder<TypeElement> builder,
+      ListMultimap<String, ExecutableElement> allMethodsByName,
+      ListMultimap<String, ExecutableElement> bindingMethodsByName) {
+    // For every @Provides method, confirm it overrides nothing *and* nothing overrides it.
+    // Consider the following hierarchy:
+    // class Parent {
+    //    @Provides Foo a() {}
+    //    @Provides Foo b() {}
+    //    Foo c() {}
+    // }
+    // class Child extends Parent {
+    //    @Provides Foo a() {}
+    //    Foo b() {}
+    //    @Provides Foo c() {}
+    // }
+    // In each of those cases, we want to fail.  "a" is clear, "b" because Child is overriding
+    // a method marked @Provides in Parent, and "c" because Child is defining an @Provides
+    // method that overrides Parent.
+    TypeElement currentClass = subject;
+    TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();
+    // We keep track of methods that failed so we don't spam with multiple failures.
+    Set<ExecutableElement> failedMethods = Sets.newHashSet();
+    while (!types.isSameType(currentClass.getSuperclass(), objectType)) {
+      currentClass = MoreElements.asType(types.asElement(currentClass.getSuperclass()));
+      List<ExecutableElement> superclassMethods =
+          ElementFilter.methodsIn(currentClass.getEnclosedElements());
+      for (ExecutableElement superclassMethod : superclassMethods) {
+        String name = superclassMethod.getSimpleName().toString();
+        // For each method in the superclass, confirm our @Provides methods don't override it
+        for (ExecutableElement providesMethod : bindingMethodsByName.get(name)) {
+          if (!failedMethods.contains(providesMethod)
+              && elements.overrides(providesMethod, superclassMethod, subject)) {
+            failedMethods.add(providesMethod);
+            builder.addError(
+                String.format(
+                    PROVIDES_METHOD_OVERRIDES_ANOTHER,
+                    methodClass.getSimpleName(),
+                    methodSignatureFormatter.format(superclassMethod)),
+                providesMethod);
+          }
+        }
+        // For each @Provides method in superclass, confirm our methods don't override it.
+        if (isAnnotationPresent(superclassMethod, methodClass)) {
+          for (ExecutableElement method : allMethodsByName.get(name)) {
+            if (!failedMethods.contains(method)
+                && elements.overrides(method, superclassMethod, subject)) {
+              failedMethods.add(method);
+              builder.addError(
+                  String.format(
+                      METHOD_OVERRIDES_PROVIDES_METHOD,
+                      methodClass.getSimpleName(),
+                      methodSignatureFormatter.format(superclassMethod)),
+                  method);
+            }
+          }
+        }
+        allMethodsByName.put(superclassMethod.getSimpleName().toString(), superclassMethod);
+      }
+    }
+  }
+
+  private void validateModuleVisibility(final TypeElement moduleElement,
+      final ValidationReport.Builder<?> reportBuilder) {
+    Visibility moduleVisibility = Visibility.ofElement(moduleElement);
+    if (moduleVisibility.equals(PRIVATE)) {
+      reportBuilder.addError("Modules cannot be private.", moduleElement);
+    } else if (effectiveVisibilityOfElement(moduleElement).equals(PRIVATE)) {
+      reportBuilder.addError("Modules cannot be enclosed in private types.", moduleElement);
+    }
+
+    switch (moduleElement.getNestingKind()) {
+      case ANONYMOUS:
+        throw new IllegalStateException("Can't apply @Module to an anonymous class");
+      case LOCAL:
+        throw new IllegalStateException("Local classes shouldn't show up in the processor");
+      case MEMBER:
+      case TOP_LEVEL:
+        if (moduleVisibility.equals(PUBLIC)) {
+          ImmutableSet<Element> nonPublicModules = FluentIterable.from(getModuleIncludes(
+              getAnnotationMirror(moduleElement, moduleClass).get()))
+                  .transform(new Function<TypeMirror, Element>() {
+                    @Override public Element apply(TypeMirror input) {
+                      return types.asElement(input);
+                    }
+                  })
+                  .filter(new Predicate<Element>() {
+                    @Override public boolean apply(Element input) {
+                      return effectiveVisibilityOfElement(input).compareTo(PUBLIC) < 0;
+                    }
+                  })
+                  .toSet();
+          if (!nonPublicModules.isEmpty()) {
+            reportBuilder.addError(
+                String.format(
+                    "This module is public, but it includes non-public "
+                        + "(or effectively non-public) modules. "
+                        + "Either reduce the visibility of this module or make %s public.",
+                    formatListForErrorMessage(nonPublicModules.asList())),
+                moduleElement);
+          }
+        }
+        break;
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private static String formatListForErrorMessage(List<?> things) {
+    switch (things.size()) {
+      case 0:
+        return "";
+      case 1:
+        return things.get(0).toString();
+      default:
+        StringBuilder output = new StringBuilder();
+        Joiner.on(", ").appendTo(output, things.subList(0, things.size() - 1));
+        output.append(" and ").append(things.get(things.size() - 1));
+        return output.toString();
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleGenerator.java b/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleGenerator.java
new file mode 100644
index 0000000..a4e020b
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleGenerator.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import dagger.Module;
+import dagger.Provides;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import dagger.producers.monitoring.internal.MonitorCache;
+
+import java.util.Set;
+import javax.annotation.Generated;
+import javax.annotation.processing.Filer;
+import javax.inject.Provider;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+import static javax.lang.model.element.Modifier.FINAL;
+
+/** Generates a monitoring module for use with production components. */
+final class MonitoringModuleGenerator extends SourceFileGenerator<TypeElement> {
+  private static final TypeName SET_OF_FACTORIES =
+      ParameterizedTypeName.create(
+          Set.class, ClassName.fromClass(ProductionComponentMonitor.Factory.class));
+
+  MonitoringModuleGenerator(Filer filer) {
+    super(filer);
+  }
+
+  @Override
+  ClassName nameGeneratedType(TypeElement componentElement) {
+    return SourceFiles.generatedMonitoringModuleName(componentElement);
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(TypeElement componentElement) {
+    return ImmutableSet.of(componentElement);
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(TypeElement componentElement) {
+    return Optional.of(componentElement);
+  }
+
+  @Override
+  ImmutableSet<JavaWriter> write(ClassName generatedTypeName, TypeElement componentElement) {
+    JavaWriter writer = JavaWriter.inPackage(generatedTypeName.packageName());
+    ClassWriter classWriter = writer.addClass(generatedTypeName.simpleName());
+    classWriter.annotate(Generated.class).setValue(ComponentProcessor.class.getName());
+    classWriter.annotate(Module.class);
+    classWriter.addModifiers(FINAL);
+
+    // TODO(beder): Replace this default set binding with EmptyCollections when it exists.
+    MethodWriter emptySetBindingMethod =
+        classWriter.addMethod(SET_OF_FACTORIES, "defaultSetOfFactories");
+    emptySetBindingMethod.addModifiers(STATIC);
+    emptySetBindingMethod.annotate(Provides.class).setMember("type", Provides.Type.SET_VALUES);
+    emptySetBindingMethod
+        .body()
+        .addSnippet("return %s.of();", ClassName.fromClass(ImmutableSet.class));
+
+    FieldWriter providerField = classWriter.addField(MonitorCache.class, "monitorCache");
+    providerField.addModifiers(PRIVATE, FINAL);
+    providerField.setInitializer("new %s()", ClassName.fromClass(MonitorCache.class));
+    MethodWriter monitorMethod = classWriter.addMethod(ProductionComponentMonitor.class, "monitor");
+    monitorMethod.annotate(Provides.class);
+    monitorMethod.addParameter(
+        ParameterizedTypeName.create(Provider.class, ClassName.fromTypeElement(componentElement)),
+        "component");
+    monitorMethod.addParameter(
+        ParameterizedTypeName.create(Provider.class, SET_OF_FACTORIES), "factories");
+    monitorMethod.body().addSnippet("return monitorCache.monitor(component, factories);");
+
+    return ImmutableSet.of(writer);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java
new file mode 100644
index 0000000..91b10e7
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import dagger.producers.ProductionComponent;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import static javax.lang.model.util.ElementFilter.typesIn;
+
+/**
+ * A processing step that is responsible for generating a special module for a
+ * {@link ProductionComponent}.
+ */
+final class MonitoringModuleProcessingStep implements ProcessingStep {
+  private final Messager messager;
+  private final MonitoringModuleGenerator monitoringModuleGenerator;
+
+  MonitoringModuleProcessingStep(
+      Messager messager, MonitoringModuleGenerator monitoringModuleGenerator) {
+    this.messager = messager;
+    this.monitoringModuleGenerator = monitoringModuleGenerator;
+  }
+
+  @Override
+  public Set<? extends Class<? extends Annotation>> annotations() {
+    return ImmutableSet.of(ProductionComponent.class);
+  }
+
+  @Override
+  public Set<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    for (TypeElement element : typesIn(elementsByAnnotation.get(ProductionComponent.class))) {
+      try {
+        monitoringModuleGenerator.generate(element);
+      } catch (SourceFileGenerationException e) {
+        e.printMessageTo(messager);
+      }
+    }
+    return ImmutableSet.of();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProducerFactoryGenerator.java b/compiler/src/main/java/dagger/internal/codegen/ProducerFactoryGenerator.java
new file mode 100644
index 0000000..90a0337
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProducerFactoryGenerator.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Provides.Type;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.ConstructorWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.Produces;
+import dagger.producers.internal.AbstractProducer;
+import dagger.producers.internal.Producers;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import java.util.List;
+import java.util.concurrent.Executor;
+import javax.annotation.Generated;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+import javax.lang.model.type.TypeMirror;
+
+import static dagger.internal.codegen.SourceFiles.frameworkTypeUsageStatement;
+import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
+import static dagger.internal.codegen.writer.Snippet.makeParametersSnippet;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PROTECTED;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * Generates {@link Producer} implementations from {@link ProductionBinding} instances.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+final class ProducerFactoryGenerator extends SourceFileGenerator<ProductionBinding> {
+  private final DependencyRequestMapper dependencyRequestMapper;
+
+  ProducerFactoryGenerator(Filer filer, DependencyRequestMapper dependencyRequestMapper) {
+    super(filer);
+    this.dependencyRequestMapper = dependencyRequestMapper;
+  }
+
+  @Override
+  ClassName nameGeneratedType(ProductionBinding binding) {
+    return generatedClassNameForBinding(binding);
+  }
+
+  @Override
+  Iterable<? extends Element> getOriginatingElements(ProductionBinding binding) {
+    return ImmutableSet.of(binding.bindingElement());
+  }
+
+  @Override
+  Optional<? extends Element> getElementForErrorReporting(ProductionBinding binding) {
+    return Optional.of(binding.bindingElement());
+  }
+
+  @Override
+  ImmutableSet<JavaWriter> write(ClassName generatedTypeName, ProductionBinding binding) {
+    TypeMirror keyType = binding.productionType().equals(Type.MAP)
+        ? Util.getProvidedValueTypeOfMap(MoreTypes.asDeclared(binding.key().type()))
+        : binding.key().type();
+    TypeName providedTypeName = TypeNames.forTypeMirror(keyType);
+    TypeName futureTypeName = ParameterizedTypeName.create(
+        ClassName.fromClass(ListenableFuture.class), providedTypeName);
+    JavaWriter writer = JavaWriter.inPackage(generatedTypeName.packageName());
+
+    ClassWriter factoryWriter = writer.addClass(generatedTypeName.simpleName());
+    ConstructorWriter constructorWriter = factoryWriter.addConstructor();
+    constructorWriter.addModifiers(PUBLIC);
+
+    ImmutableMap<BindingKey, FrameworkField> fields =
+        SourceFiles.generateBindingFieldsForDependencies(
+            dependencyRequestMapper, binding.implicitDependencies());
+
+    constructorWriter
+        .body()
+        .addSnippet(
+            "super(%s, %s.create(%s.class));",
+            fields.get(binding.monitorRequest().get().bindingKey()).name(),
+            ClassName.fromClass(ProducerToken.class),
+            factoryWriter.name());
+
+    if (!binding.bindingElement().getModifiers().contains(STATIC)) {
+      factoryWriter.addField(binding.bindingTypeElement(), "module")
+          .addModifiers(PRIVATE, FINAL);
+      constructorWriter.addParameter(binding.bindingTypeElement(), "module");
+      constructorWriter.body()
+          .addSnippet("assert module != null;")
+          .addSnippet("this.module = module;");
+    }
+
+    factoryWriter.addField(Executor.class, "executor")
+        .addModifiers(PRIVATE, FINAL);
+    constructorWriter.addParameter(Executor.class, "executor");
+    constructorWriter.body()
+        .addSnippet("assert executor != null;")
+        .addSnippet("this.executor = executor;");
+
+    factoryWriter.annotate(Generated.class).setValue(ComponentProcessor.class.getName());
+    factoryWriter.addModifiers(PUBLIC);
+    factoryWriter.addModifiers(FINAL);
+    factoryWriter.setSuperclass(
+        ParameterizedTypeName.create(AbstractProducer.class, providedTypeName));
+
+    MethodWriter computeMethodWriter = factoryWriter.addMethod(futureTypeName, "compute");
+    computeMethodWriter.annotate(Override.class);
+    computeMethodWriter.addModifiers(PROTECTED);
+    computeMethodWriter.addParameter(ProducerMonitor.class, "monitor").addModifiers(FINAL);
+
+    for (FrameworkField bindingField : fields.values()) {
+      TypeName fieldType = bindingField.frameworkType();
+      FieldWriter field = factoryWriter.addField(fieldType, bindingField.name());
+      field.addModifiers(PRIVATE, FINAL);
+      constructorWriter.addParameter(field.type(), field.name());
+      constructorWriter.body()
+          .addSnippet("assert %s != null;", field.name())
+          .addSnippet("this.%1$s = %1$s;", field.name());
+    }
+
+    boolean returnsFuture =
+        binding.bindingKind().equals(ContributionBinding.Kind.FUTURE_PRODUCTION);
+    ImmutableList<DependencyRequest> asyncDependencies =
+        FluentIterable.from(binding.implicitDependencies())
+            .filter(
+                new Predicate<DependencyRequest>() {
+                  @Override
+                  public boolean apply(DependencyRequest dependency) {
+                    return isAsyncDependency(dependency);
+                  }
+                })
+            .toList();
+
+    for (DependencyRequest dependency : asyncDependencies) {
+      ParameterizedTypeName futureType = ParameterizedTypeName.create(
+          ClassName.fromClass(ListenableFuture.class),
+          asyncDependencyType(dependency));
+      String name = fields.get(dependency.bindingKey()).name();
+      Snippet futureAccess = Snippet.format("%s.get()", name);
+      computeMethodWriter
+          .body()
+          .addSnippet(
+              "%s %sFuture = %s;",
+              futureType,
+              name,
+              dependency.kind().equals(DependencyRequest.Kind.PRODUCED)
+                  ? Snippet.format(
+                      "%s.createFutureProduced(%s)",
+                      ClassName.fromClass(Producers.class),
+                      futureAccess)
+                  : futureAccess);
+    }
+
+    FutureTransform futureTransform = FutureTransform.create(fields, binding, asyncDependencies);
+    Snippet transformSnippet =
+        Snippet.format(
+            Joiner.on('\n')
+                .join(
+                    "new %1$s<%2$s, %3$s>() {",
+                    "  %4$s",
+                    "  @Override public %5$s apply(%2$s %6$s) %7$s {",
+                    "    %8$s",
+                    "  }",
+                    "}"),
+            ClassName.fromClass(AsyncFunction.class),
+            futureTransform.applyArgType(),
+            providedTypeName,
+            futureTransform.hasUncheckedCast()
+                ? "@SuppressWarnings(\"unchecked\")  // safe by specification"
+                : "",
+            futureTypeName,
+            futureTransform.applyArgName(),
+            getThrowsClause(binding.thrownTypes()),
+            getInvocationSnippet(!returnsFuture, binding, futureTransform.parameterSnippets()));
+    computeMethodWriter
+        .body()
+        .addSnippet(
+            "return %s.transform(%s, %s, executor);",
+            ClassName.fromClass(Futures.class),
+            futureTransform.futureSnippet(),
+            transformSnippet);
+
+    // TODO(gak): write a sensible toString
+    return ImmutableSet.of(writer);
+  }
+
+  /** Represents the transformation of an input future by a producer method. */
+  abstract static class FutureTransform {
+    protected final ImmutableMap<BindingKey, FrameworkField> fields;
+    protected final ProductionBinding binding;
+
+    FutureTransform(ImmutableMap<BindingKey, FrameworkField> fields, ProductionBinding binding) {
+      this.fields = fields;
+      this.binding = binding;
+    }
+
+    /** The snippet representing the future that should be transformed. */
+    abstract Snippet futureSnippet();
+
+    /** The type of the argument to the apply method. */
+    abstract TypeName applyArgType();
+
+    /** The name of the argument to the apply method */
+    abstract String applyArgName();
+
+    /** The snippets to be passed to the produces method itself. */
+    abstract ImmutableList<Snippet> parameterSnippets();
+
+    /** Whether the transform method has an unchecked cast. */
+    boolean hasUncheckedCast() {
+      return false;
+    }
+
+    static FutureTransform create(
+        ImmutableMap<BindingKey, FrameworkField> fields,
+        ProductionBinding binding,
+        ImmutableList<DependencyRequest> asyncDependencies) {
+      if (asyncDependencies.isEmpty()) {
+        return new NoArgFutureTransform(fields, binding);
+      } else if (asyncDependencies.size() == 1) {
+        return new SingleArgFutureTransform(
+            fields, binding, Iterables.getOnlyElement(asyncDependencies));
+      } else {
+        return new MultiArgFutureTransform(fields, binding, asyncDependencies);
+      }
+    }
+  }
+
+  static final class NoArgFutureTransform extends FutureTransform {
+    NoArgFutureTransform(
+        ImmutableMap<BindingKey, FrameworkField> fields, ProductionBinding binding) {
+      super(fields, binding);
+    }
+
+    @Override
+    Snippet futureSnippet() {
+      return Snippet.format(
+          "%s.<%s>immediateFuture(null)",
+          ClassName.fromClass(Futures.class),
+          ClassName.fromClass(Void.class));
+    }
+
+    @Override
+    TypeName applyArgType() {
+      return ClassName.fromClass(Void.class);
+    }
+
+    @Override
+    String applyArgName() {
+      return "ignoredVoidArg";
+    }
+
+    @Override
+    ImmutableList<Snippet> parameterSnippets() {
+      ImmutableList.Builder<Snippet> parameterSnippets = ImmutableList.builder();
+      for (DependencyRequest dependency : binding.dependencies()) {
+        parameterSnippets.add(
+            frameworkTypeUsageStatement(
+                Snippet.format(
+                    "%s", fields.get(dependency.bindingKey()).name()), dependency.kind()));
+      }
+      return parameterSnippets.build();
+    }
+  }
+
+  static final class SingleArgFutureTransform extends FutureTransform {
+    private final DependencyRequest asyncDependency;
+
+    SingleArgFutureTransform(
+        ImmutableMap<BindingKey, FrameworkField> fields,
+        ProductionBinding binding,
+        DependencyRequest asyncDependency) {
+      super(fields, binding);
+      this.asyncDependency = asyncDependency;
+    }
+
+    @Override
+    Snippet futureSnippet() {
+      return Snippet.format("%s", fields.get(asyncDependency.bindingKey()).name() + "Future");
+    }
+
+    @Override
+    TypeName applyArgType() {
+      return asyncDependencyType(asyncDependency);
+    }
+
+    @Override
+    String applyArgName() {
+      return asyncDependency.requestElement().getSimpleName().toString();
+    }
+
+    @Override
+    ImmutableList<Snippet> parameterSnippets() {
+      ImmutableList.Builder<Snippet> parameterSnippets = ImmutableList.builder();
+      for (DependencyRequest dependency : binding.dependencies()) {
+        // We really want to compare instances here, because asyncDependency is an element in the
+        // set binding.dependencies().
+        if (dependency == asyncDependency) {
+          parameterSnippets.add(Snippet.format("%s", applyArgName()));
+        } else {
+          parameterSnippets.add(
+              frameworkTypeUsageStatement(
+                  Snippet.format(
+                      "%s", fields.get(dependency.bindingKey()).name()), dependency.kind()));
+        }
+      }
+      return parameterSnippets.build();
+    }
+  }
+
+  static final class MultiArgFutureTransform extends FutureTransform {
+    private final ImmutableList<DependencyRequest> asyncDependencies;
+
+    MultiArgFutureTransform(
+        ImmutableMap<BindingKey, FrameworkField> fields,
+        ProductionBinding binding,
+        ImmutableList<DependencyRequest> asyncDependencies) {
+      super(fields, binding);
+      this.asyncDependencies = asyncDependencies;
+    }
+
+    @Override
+    Snippet futureSnippet() {
+      return Snippet.format(
+          "%s.<%s>allAsList(%s)",
+          ClassName.fromClass(Futures.class),
+          ClassName.fromClass(Object.class),
+          makeParametersSnippet(
+              FluentIterable.from(asyncDependencies)
+                  .transform(DependencyRequest.BINDING_KEY_FUNCTION)
+                  .transform(
+                      new Function<BindingKey, Snippet>() {
+                        @Override
+                        public Snippet apply(BindingKey bindingKey) {
+                          return Snippet.format("%s", fields.get(bindingKey).name() + "Future");
+                        }
+                      })));
+    }
+
+    @Override
+    TypeName applyArgType() {
+      return ParameterizedTypeName.create(
+          ClassName.fromClass(List.class), ClassName.fromClass(Object.class));
+    }
+
+    @Override
+    String applyArgName() {
+      return "args";
+    }
+
+    @Override
+    ImmutableList<Snippet> parameterSnippets() {
+      return getParameterSnippets(binding, fields, applyArgName());
+    }
+
+    @Override
+    boolean hasUncheckedCast() {
+      return true;
+    }
+  }
+
+  private static boolean isAsyncDependency(DependencyRequest dependency) {
+    switch (dependency.kind()) {
+      case INSTANCE:
+      case PRODUCED:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  private static TypeName asyncDependencyType(DependencyRequest dependency) {
+    TypeName keyName = TypeNames.forTypeMirror(dependency.key().type());
+    switch (dependency.kind()) {
+      case INSTANCE:
+        return keyName;
+      case PRODUCED:
+        return ParameterizedTypeName.create(ClassName.fromClass(Produced.class), keyName);
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  private static ImmutableList<Snippet> getParameterSnippets(
+      ProductionBinding binding,
+      ImmutableMap<BindingKey, FrameworkField> fields,
+      String listArgName) {
+    int argIndex = 0;
+    ImmutableList.Builder<Snippet> snippets = ImmutableList.builder();
+    for (DependencyRequest dependency : binding.dependencies()) {
+      if (isAsyncDependency(dependency)) {
+        snippets.add(Snippet.format(
+            "(%s) %s.get(%s)",
+            asyncDependencyType(dependency),
+            listArgName,
+            argIndex));
+        argIndex++;
+      } else {
+        snippets.add(frameworkTypeUsageStatement(
+            Snippet.format("%s", fields.get(dependency.bindingKey()).name()), dependency.kind()));
+      }
+    }
+    return snippets.build();
+  }
+
+  /**
+   * Creates a snippet for the invocation of the producer method from the module, which should be
+   * used entirely within a method body.
+   *
+   * @param wrapWithFuture If true, wraps the result of the call to the producer method
+   *        in an immediate future.
+   * @param binding The binding to generate the invocation snippet for.
+   * @param parameterSnippets The snippets for all the parameters to the producer method.
+   */
+  private Snippet getInvocationSnippet(
+      boolean wrapWithFuture, ProductionBinding binding, ImmutableList<Snippet> parameterSnippets) {
+     Snippet moduleSnippet = Snippet.format("%s.%s(%s)",
+        binding.bindingElement().getModifiers().contains(STATIC)
+            ? ClassName.fromTypeElement(binding.bindingTypeElement())
+            : "module",
+        binding.bindingElement().getSimpleName(),
+        makeParametersSnippet(parameterSnippets));
+
+    // NOTE(beder): We don't worry about catching exeptions from the monitor methods themselves
+    // because we'll wrap all monitoring in non-throwing monitors before we pass them to the
+    // factories.
+    ImmutableList.Builder<Snippet> snippets = ImmutableList.builder();
+    snippets.add(Snippet.format("monitor.methodStarting();"));
+
+    final Snippet valueSnippet;
+    if (binding.productionType().equals(Produces.Type.SET)) {
+      if (binding.bindingKind().equals(ContributionBinding.Kind.FUTURE_PRODUCTION)) {
+        valueSnippet =
+            Snippet.format(
+                "%s.createFutureSingletonSet(%s)",
+                ClassName.fromClass(Producers.class),
+                moduleSnippet);
+      } else {
+        valueSnippet =
+            Snippet.format("%s.of(%s)", ClassName.fromClass(ImmutableSet.class), moduleSnippet);
+      }
+    } else {
+      valueSnippet = moduleSnippet;
+    }
+    Snippet returnSnippet =
+        wrapWithFuture
+            ? Snippet.format(
+                "%s.<%s>immediateFuture(%s)",
+                ClassName.fromClass(Futures.class),
+                TypeNames.forTypeMirror(binding.key().type()),
+                valueSnippet)
+            : valueSnippet;
+    return Snippet.format(
+        Joiner.on('\n')
+            .join(
+                "monitor.methodStarting();",
+                "try {",
+                "  return %s;",
+                "} finally {",
+                "  monitor.methodFinished();",
+                "}"),
+        returnSnippet);
+  }
+
+  /**
+   * Creates a Snippet for the throws clause.
+   *
+   * @param thrownTypes the list of thrown types.
+   */
+  private Snippet getThrowsClause(List<? extends TypeMirror> thrownTypes) {
+    if (thrownTypes.isEmpty()) {
+      return Snippet.format("");
+    }
+    return Snippet.format("throws %s ",
+        Snippet.makeParametersSnippet(FluentIterable
+            .from(thrownTypes)
+            .transform(new Function<TypeMirror, Snippet>() {
+              @Override public Snippet apply(TypeMirror thrownType) {
+                return Snippet.format("%s", TypeNames.forTypeMirror(thrownType));
+              }
+            })
+            .toList()));
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProducerModuleProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/ProducerModuleProcessingStep.java
new file mode 100644
index 0000000..cc167e5
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProducerModuleProcessingStep.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.SuperficialValidation;
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static javax.lang.model.element.ElementKind.METHOD;
+
+/**
+ * An annotation processor for generating Dagger implementation code based on the
+ * {@link ProducerModule} (and {@link Produces}) annotation.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+final class ProducerModuleProcessingStep implements ProcessingStep {
+  private final Messager messager;
+  private final ModuleValidator moduleValidator;
+  private final ProducesMethodValidator producesMethodValidator;
+  private final ProductionBinding.Factory productionBindingFactory;
+  private final ProducerFactoryGenerator factoryGenerator;
+  private final Set<Element> processedModuleElements = Sets.newLinkedHashSet();
+
+  ProducerModuleProcessingStep(
+      Messager messager,
+      ModuleValidator moduleValidator,
+      ProducesMethodValidator producesMethodValidator,
+      ProductionBinding.Factory productionBindingFactory,
+      ProducerFactoryGenerator factoryGenerator) {
+    this.messager = messager;
+    this.moduleValidator = moduleValidator;
+    this.producesMethodValidator = producesMethodValidator;
+    this.productionBindingFactory = productionBindingFactory;
+    this.factoryGenerator = factoryGenerator;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.of(Produces.class, ProducerModule.class);
+  }
+
+  @Override
+  public Set<Element> process(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    // first, check and collect all produces methods
+    ImmutableSet.Builder<ExecutableElement> validProducesMethodsBuilder = ImmutableSet.builder();
+    for (Element producesElement : elementsByAnnotation.get(Produces.class)) {
+      if (producesElement.getKind().equals(METHOD)) {
+        ExecutableElement producesMethodElement = (ExecutableElement) producesElement;
+        ValidationReport<ExecutableElement> methodReport =
+            producesMethodValidator.validate(producesMethodElement);
+        methodReport.printMessagesTo(messager);
+        if (methodReport.isClean()) {
+          validProducesMethodsBuilder.add(producesMethodElement);
+        }
+      }
+    }
+    ImmutableSet<ExecutableElement> validProducesMethods = validProducesMethodsBuilder.build();
+
+    // process each module
+    for (Element moduleElement :
+        Sets.difference(elementsByAnnotation.get(ProducerModule.class),
+            processedModuleElements)) {
+      if (SuperficialValidation.validateElement(moduleElement)) {
+        ValidationReport<TypeElement> report =
+            moduleValidator.validate(MoreElements.asType(moduleElement));
+        report.printMessagesTo(messager);
+
+        if (report.isClean()) {
+          ImmutableSet.Builder<ExecutableElement> moduleProducesMethodsBuilder =
+              ImmutableSet.builder();
+          List<ExecutableElement> moduleMethods =
+              ElementFilter.methodsIn(moduleElement.getEnclosedElements());
+          for (ExecutableElement methodElement : moduleMethods) {
+            if (isAnnotationPresent(methodElement, Produces.class)) {
+              moduleProducesMethodsBuilder.add(methodElement);
+            }
+          }
+          ImmutableSet<ExecutableElement> moduleProducesMethods =
+              moduleProducesMethodsBuilder.build();
+
+          if (Sets.difference(moduleProducesMethods, validProducesMethods).isEmpty()) {
+            // all of the produces methods in this module are valid!
+            // time to generate some factories!
+            ImmutableSet<ProductionBinding> bindings = FluentIterable.from(moduleProducesMethods)
+                .transform(new Function<ExecutableElement, ProductionBinding>() {
+                  @Override
+                  public ProductionBinding apply(ExecutableElement producesMethod) {
+                    return productionBindingFactory.forProducesMethod(producesMethod,
+                        producesMethod.getEnclosingElement().asType());
+                  }
+                })
+                .toSet();
+
+            try {
+              for (ProductionBinding binding : bindings) {
+                factoryGenerator.generate(binding);
+              }
+            } catch (SourceFileGenerationException e) {
+              e.printMessageTo(messager);
+            }
+          }
+        }
+
+        processedModuleElements.add(moduleElement);
+      }
+    }
+    return ImmutableSet.of();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProducesMethodValidator.java b/compiler/src/main/java/dagger/internal/codegen/ProducesMethodValidator.java
new file mode 100644
index 0000000..b0b4df1
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProducesMethodValidator.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_MUST_RETURN_A_VALUE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_IN_MODULE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_MAP_HAS_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_PRIVATE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_SET_VALUES_RAW_SET;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_TYPE_PARAMETER;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_MULTIPLE_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_NO_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_RAW_FUTURE;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_RETURN_TYPE;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_SET_VALUES_RETURN_SET;
+import static dagger.internal.codegen.MapKeys.getMapKeys;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.type.TypeKind.ARRAY;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.VOID;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Produces} methods.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+// TODO(user): Consider unifying this with the ProvidesMethodValidator after Provides.Type and
+// Produces.Type are reconciled.
+final class ProducesMethodValidator {
+  private final Elements elements;
+
+  ProducesMethodValidator(Elements elements) {
+    this.elements = checkNotNull(elements);
+  }
+
+  private TypeElement getSetElement() {
+    return elements.getTypeElement(Set.class.getCanonicalName());
+  }
+
+  ValidationReport<ExecutableElement> validate(ExecutableElement producesMethodElement) {
+    ValidationReport.Builder<ExecutableElement> builder =
+        ValidationReport.about(producesMethodElement);
+
+    Produces producesAnnotation = producesMethodElement.getAnnotation(Produces.class);
+    checkArgument(producesAnnotation != null);
+
+    Element enclosingElement = producesMethodElement.getEnclosingElement();
+    if (!isAnnotationPresent(enclosingElement, ProducerModule.class)) {
+      builder.addError(
+          formatModuleErrorMessage(BINDING_METHOD_NOT_IN_MODULE), producesMethodElement);
+    }
+
+    if (!producesMethodElement.getTypeParameters().isEmpty()) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_TYPE_PARAMETER), producesMethodElement);
+    }
+
+    Set<Modifier> modifiers = producesMethodElement.getModifiers();
+    if (modifiers.contains(PRIVATE)) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_PRIVATE), producesMethodElement);
+    }
+    if (modifiers.contains(ABSTRACT)) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_ABSTRACT), producesMethodElement);
+    }
+
+    TypeMirror returnType = producesMethodElement.getReturnType();
+    TypeKind returnTypeKind = returnType.getKind();
+    if (returnTypeKind.equals(VOID)) {
+      builder.addError(
+          formatErrorMessage(BINDING_METHOD_MUST_RETURN_A_VALUE), producesMethodElement);
+    }
+
+    // check mapkey is right
+    if (!producesAnnotation.type().equals(Produces.Type.MAP)
+        && !getMapKeys(producesMethodElement).isEmpty()) {
+      builder.addError(
+          formatErrorMessage(BINDING_METHOD_NOT_MAP_HAS_MAP_KEY), producesMethodElement);
+    }
+
+    ProvidesMethodValidator.validateMethodQualifiers(builder, producesMethodElement);
+
+    switch (producesAnnotation.type()) {
+      case UNIQUE: // fall through
+      case SET:
+        validateSingleReturnType(builder, returnType);
+        break;
+      case MAP:
+        validateSingleReturnType(builder, returnType);
+        ImmutableSet<? extends AnnotationMirror> mapKeys = getMapKeys(producesMethodElement);
+        switch (mapKeys.size()) {
+          case 0:
+            builder.addError(
+                formatErrorMessage(BINDING_METHOD_WITH_NO_MAP_KEY), producesMethodElement);
+            break;
+          case 1:
+            break;
+          default:
+            builder.addError(
+                formatErrorMessage(BINDING_METHOD_WITH_MULTIPLE_MAP_KEY), producesMethodElement);
+            break;
+        }
+        break;
+      case SET_VALUES:
+        if (returnTypeKind.equals(DECLARED)
+            && MoreTypes.isTypeOf(ListenableFuture.class, returnType)) {
+          DeclaredType declaredReturnType = MoreTypes.asDeclared(returnType);
+          if (!declaredReturnType.getTypeArguments().isEmpty()) {
+            validateSetType(builder, Iterables.getOnlyElement(
+                declaredReturnType.getTypeArguments()));
+          }
+        } else {
+          validateSetType(builder, returnType);
+        }
+        break;
+      default:
+        throw new AssertionError();
+    }
+
+    return builder.build();
+  }
+
+  private String formatErrorMessage(String msg) {
+    return String.format(msg, Produces.class.getSimpleName());
+  }
+
+  private String formatModuleErrorMessage(String msg) {
+    return String.format(msg, Produces.class.getSimpleName(), ProducerModule.class.getSimpleName());
+  }
+
+  private void validateKeyType(ValidationReport.Builder<? extends Element> reportBuilder,
+      TypeMirror type) {
+    TypeKind kind = type.getKind();
+    if (!(kind.isPrimitive() || kind.equals(DECLARED) || kind.equals(ARRAY))) {
+      reportBuilder.addError(PRODUCES_METHOD_RETURN_TYPE, reportBuilder.getSubject());
+    }
+  }
+
+  private void validateSingleReturnType(ValidationReport.Builder<? extends Element> reportBuilder,
+      TypeMirror type) {
+    if (type.getKind().equals(DECLARED) && MoreTypes.isTypeOf(ListenableFuture.class, type)) {
+      DeclaredType declaredType = MoreTypes.asDeclared(type);
+      if (declaredType.getTypeArguments().isEmpty()) {
+        reportBuilder.addError(PRODUCES_METHOD_RAW_FUTURE, reportBuilder.getSubject());
+      } else {
+        validateKeyType(reportBuilder, Iterables.getOnlyElement(declaredType.getTypeArguments()));
+      }
+    } else {
+      validateKeyType(reportBuilder, type);
+    }
+  }
+
+  private void validateSetType(ValidationReport.Builder<? extends Element> reportBuilder,
+      TypeMirror type) {
+    if (!type.getKind().equals(DECLARED)) {
+      reportBuilder.addError(PRODUCES_METHOD_SET_VALUES_RETURN_SET, reportBuilder.getSubject());
+      return;
+    }
+
+    // TODO(gak): should we allow "covariant return" for set values?
+    DeclaredType declaredType = MoreTypes.asDeclared(type);
+    if (!declaredType.asElement().equals(getSetElement())) {
+      reportBuilder.addError(PRODUCES_METHOD_SET_VALUES_RETURN_SET, reportBuilder.getSubject());
+    } else if (declaredType.getTypeArguments().isEmpty()) {
+      reportBuilder.addError(
+          formatErrorMessage(BINDING_METHOD_SET_VALUES_RAW_SET), reportBuilder.getSubject());
+    } else {
+      validateSingleReturnType(reportBuilder,
+          Iterables.getOnlyElement(declaredType.getTypeArguments()));
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProductionBinding.java b/compiler/src/main/java/dagger/internal/codegen/ProductionBinding.java
new file mode 100644
index 0000000..1666fbf
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProductionBinding.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Provides;
+import dagger.producers.Produces;
+import java.util.Set;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.lang.model.element.ElementKind.METHOD;
+
+/**
+ * A value object representing the mechanism by which a {@link Key} can be produced. New instances
+ * should be created using an instance of the {@link Factory}.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+@AutoValue
+abstract class ProductionBinding extends ContributionBinding {
+
+  @Override
+  Binding.Type bindingType() {
+    return Binding.Type.PRODUCTION;
+  }
+
+  @Override
+  Provides.Type provisionType() {
+    return Provides.Type.valueOf(productionType().name());
+  }
+
+  @Override
+  Set<DependencyRequest> implicitDependencies() {
+    // Similar optimizations to ContributionBinding.implicitDependencies().
+    if (!monitorRequest().isPresent()) {
+      return super.implicitDependencies();
+    } else {
+      return Sets.union(monitorRequest().asSet(), super.implicitDependencies());
+    }
+  }
+
+  /** Returns provision type that was used to bind the key. */
+  abstract Produces.Type productionType();
+
+  /** Returns the list of types in the throws clause of the method. */
+  abstract ImmutableList<? extends TypeMirror> thrownTypes();
+
+  /** If this production requires a monitor, this will be the corresponding request. */
+  abstract Optional<DependencyRequest> monitorRequest();
+
+  @Override
+  ContributionType contributionType() {
+    switch (productionType()) {
+      case SET:
+      case SET_VALUES:
+        return ContributionType.SET;
+      case MAP:
+        return ContributionType.MAP;
+      case UNIQUE:
+        return ContributionType.UNIQUE;
+      default:
+        throw new AssertionError("Unknown production type: " + productionType());
+    }
+  }
+
+  static final class Factory {
+    private final Types types;
+    private final Key.Factory keyFactory;
+    private final DependencyRequest.Factory dependencyRequestFactory;
+
+    Factory(
+        Types types, Key.Factory keyFactory, DependencyRequest.Factory dependencyRequestFactory) {
+      this.types = types;
+      this.keyFactory = keyFactory;
+      this.dependencyRequestFactory = dependencyRequestFactory;
+    }
+
+    ProductionBinding forProducesMethod(
+        ExecutableElement producesMethod, TypeMirror contributedBy) {
+      checkNotNull(producesMethod);
+      checkArgument(producesMethod.getKind().equals(METHOD));
+      checkArgument(contributedBy.getKind().equals(TypeKind.DECLARED));
+      Produces producesAnnotation = producesMethod.getAnnotation(Produces.class);
+      checkArgument(producesAnnotation != null);
+      DeclaredType declaredContainer = MoreTypes.asDeclared(contributedBy);
+      ExecutableType resolvedMethod =
+          MoreTypes.asExecutable(types.asMemberOf(declaredContainer, producesMethod));
+      Key key = keyFactory.forProducesMethod(resolvedMethod, producesMethod);
+      ImmutableSet<DependencyRequest> dependencies =
+          dependencyRequestFactory.forRequiredResolvedVariables(
+              declaredContainer,
+              producesMethod.getParameters(),
+              resolvedMethod.getParameterTypes());
+      DependencyRequest monitorRequest =
+          dependencyRequestFactory.forProductionComponentMonitorProvider();
+      Kind kind = MoreTypes.isTypeOf(ListenableFuture.class, producesMethod.getReturnType())
+          ? Kind.FUTURE_PRODUCTION
+          : Kind.IMMEDIATE;
+      return new AutoValue_ProductionBinding(
+          key,
+          producesMethod,
+          dependencies,
+          findBindingPackage(key),
+          false,
+          ConfigurationAnnotations.getNullableType(producesMethod),
+          Optional.of(MoreTypes.asTypeElement(declaredContainer)),
+          Optional.<DependencyRequest>absent(),
+          kind,
+          producesAnnotation.type(),
+          ImmutableList.copyOf(producesMethod.getThrownTypes()),
+          Optional.of(monitorRequest));
+    }
+
+    ProductionBinding implicitMapOfProducerBinding(DependencyRequest mapOfValueRequest) {
+      checkNotNull(mapOfValueRequest);
+      Optional<Key> implicitMapOfProducerKey =
+          keyFactory.implicitMapProducerKeyFrom(mapOfValueRequest.key());
+      checkArgument(
+          implicitMapOfProducerKey.isPresent(), "%s is not for a Map<K, V>", mapOfValueRequest);
+      DependencyRequest implicitMapOfProducerRequest =
+          dependencyRequestFactory.forImplicitMapBinding(
+              mapOfValueRequest, implicitMapOfProducerKey.get());
+      return new AutoValue_ProductionBinding(
+          mapOfValueRequest.key(),
+          implicitMapOfProducerRequest.requestElement(),
+          ImmutableSet.of(implicitMapOfProducerRequest),
+          findBindingPackage(mapOfValueRequest.key()),
+          false,
+          Optional.<DeclaredType>absent(),
+          Optional.<TypeElement>absent(),
+          Optional.<DependencyRequest>absent(),
+          Kind.SYNTHETIC,
+          Produces.Type.MAP,
+          ImmutableList.<TypeMirror>of(),
+          Optional.<DependencyRequest>absent());
+    }
+
+    ProductionBinding forComponentMethod(ExecutableElement componentMethod) {
+      checkNotNull(componentMethod);
+      checkArgument(componentMethod.getKind().equals(METHOD));
+      checkArgument(componentMethod.getParameters().isEmpty());
+      checkArgument(MoreTypes.isTypeOf(ListenableFuture.class, componentMethod.getReturnType()));
+      return new AutoValue_ProductionBinding(
+          keyFactory.forProductionComponentMethod(componentMethod),
+          componentMethod,
+          ImmutableSet.<DependencyRequest>of(),
+          Optional.<String>absent(),
+          false,
+          Optional.<DeclaredType>absent(),
+          Optional.<TypeElement>absent(),
+          Optional.<DependencyRequest>absent(),
+          Kind.COMPONENT_PRODUCTION,
+          Produces.Type.UNIQUE,
+          ImmutableList.copyOf(componentMethod.getThrownTypes()),
+          Optional.<DependencyRequest>absent());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProductionComponentProcessingStep.java b/compiler/src/main/java/dagger/internal/codegen/ProductionComponentProcessingStep.java
new file mode 100644
index 0000000..0581b1b
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProductionComponentProcessingStep.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.auto.common.MoreElements;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.SetMultimap;
+import dagger.producers.ProductionComponent;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * A {@link ProcessingStep} that is responsible for dealing with the {@link ProductionComponent}
+ * annotation as part of the {@link ComponentProcessor}.
+ *
+ * @author Jesse Beder
+ */
+final class ProductionComponentProcessingStep extends AbstractComponentProcessingStep {
+  private final Messager messager;
+  private final ProductionComponentValidator componentValidator;
+  private final BuilderValidator componentBuilderValidator;
+
+  ProductionComponentProcessingStep(
+      Messager messager,
+      ProductionComponentValidator componentValidator,
+      BuilderValidator componentBuilderValidator,
+      ComponentHierarchyValidator componentHierarchyValidator,
+      BindingGraphValidator bindingGraphValidator,
+      ComponentDescriptor.Factory componentDescriptorFactory,
+      BindingGraph.Factory bindingGraphFactory,
+      ComponentGenerator componentGenerator) {
+    super(
+        ProductionComponent.class,
+        messager,
+        componentHierarchyValidator,
+        bindingGraphValidator,
+        componentDescriptorFactory,
+        bindingGraphFactory,
+        componentGenerator);
+    this.messager = messager;
+    this.componentValidator = componentValidator;
+    this.componentBuilderValidator = componentBuilderValidator;
+  }
+
+  @Override
+  public Set<Class<? extends Annotation>> annotations() {
+    return ImmutableSet.<Class<? extends Annotation>>of(
+        ProductionComponent.class, ProductionComponent.Builder.class);
+  }
+
+  // TODO(beder): Move common logic into the AbstractComponentProcessingStep when implementing
+  // production subcomponents.
+  @Override
+  protected ComponentElementValidator componentElementValidator(
+      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+    final Map<Element, ValidationReport<TypeElement>> builderReportsByComponent =
+        processComponentBuilders(elementsByAnnotation.get(ProductionComponent.Builder.class));
+    return new ComponentElementValidator() {
+      @Override
+      boolean validateComponent(TypeElement componentTypeElement, Messager messager) {
+        ValidationReport<TypeElement> validationReport =
+            componentValidator.validate(componentTypeElement);
+        validationReport.printMessagesTo(messager);
+        if (!validationReport.isClean()) {
+          return false;
+        }
+        ValidationReport<?> builderReport = builderReportsByComponent.get(componentTypeElement);
+        return builderReport == null || builderReport.isClean();
+      }
+    };
+  }
+
+  private Map<Element, ValidationReport<TypeElement>> processComponentBuilders(
+      Set<? extends Element> componentBuilderElements) {
+    Map<Element, ValidationReport<TypeElement>> builderReportsByComponent = Maps.newHashMap();
+    for (Element element : componentBuilderElements) {
+      ValidationReport<TypeElement> report =
+          componentBuilderValidator.validate(MoreElements.asType(element));
+      report.printMessagesTo(messager);
+      builderReportsByComponent.put(element.getEnclosingElement(), report);
+    }
+    return builderReportsByComponent;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProductionComponentValidator.java b/compiler/src/main/java/dagger/internal/codegen/ProductionComponentValidator.java
new file mode 100644
index 0000000..2e2291d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProductionComponentValidator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.common.collect.ImmutableList;
+import dagger.Module;
+import dagger.producers.ProducerModule;
+import dagger.producers.ProductionComponent;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.common.base.Preconditions.checkState;
+import static dagger.internal.codegen.ConfigurationAnnotations.getComponentModules;
+import static javax.lang.model.element.ElementKind.CLASS;
+import static javax.lang.model.element.ElementKind.INTERFACE;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+
+/**
+ * Performs superficial validation of the contract of the {@link ProductionComponent} annotation.
+ *
+ * @author Jesse Beder
+ */
+final class ProductionComponentValidator {
+  ValidationReport<TypeElement> validate(final TypeElement subject) {
+    final ValidationReport.Builder<TypeElement> builder = ValidationReport.about(subject);
+
+    if (!subject.getKind().equals(INTERFACE)
+        && !(subject.getKind().equals(CLASS) && subject.getModifiers().contains(ABSTRACT))) {
+      builder.addError(
+          "@ProductionComponent may only be applied to an interface or abstract class", subject);
+    }
+
+    AnnotationMirror componentMirror =
+        getAnnotationMirror(subject, ProductionComponent.class).get();
+    ImmutableList<TypeMirror> moduleTypes = getComponentModules(componentMirror);
+
+    // TODO(gak): make unused modules an error
+    for (TypeMirror moduleType : moduleTypes) {
+      moduleType.accept(
+          new SimpleTypeVisitor6<Void, Void>() {
+            @Override
+            protected Void defaultAction(TypeMirror mirror, Void p) {
+              builder.addError(mirror + " is not a valid module type.", subject);
+              return null;
+            }
+
+            @Override
+            public Void visitDeclared(DeclaredType t, Void p) {
+              checkState(t.getTypeArguments().isEmpty());
+              TypeElement moduleElement = MoreElements.asType(t.asElement());
+              if (!getAnnotationMirror(moduleElement, Module.class).isPresent()
+                  && !getAnnotationMirror(moduleElement, ProducerModule.class).isPresent()) {
+                builder.addError(
+                    moduleElement.getQualifiedName()
+                        + " is listed as a module, but is not annotated with @Module or"
+                        + " @ProducerModule",
+                    subject);
+              }
+              return null;
+            }
+          },
+          null);
+    }
+
+    return builder.build();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProvidesMethodValidator.java b/compiler/src/main/java/dagger/internal/codegen/ProvidesMethodValidator.java
new file mode 100644
index 0000000..e9c8b16
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProvidesMethodValidator.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import dagger.Module;
+import dagger.Provides;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_MUST_RETURN_A_VALUE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_IN_MODULE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_MAP_HAS_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_PRIVATE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_SET_VALUES_RAW_SET;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_TYPE_PARAMETER;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_MULTIPLE_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_NO_MAP_KEY;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_METHOD_RETURN_TYPE;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_METHOD_SET_VALUES_RETURN_SET;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS;
+import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
+import static dagger.internal.codegen.MapKeys.getMapKeys;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.type.TypeKind.ARRAY;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.VOID;
+
+/**
+ * A {@linkplain ValidationReport validator} for {@link Provides} methods.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class ProvidesMethodValidator {
+  private final Elements elements;
+
+  ProvidesMethodValidator(Elements elements) {
+    this.elements = checkNotNull(elements);
+  }
+
+  private TypeElement getSetElement() {
+    return elements.getTypeElement(Set.class.getCanonicalName());
+  }
+
+  ValidationReport<ExecutableElement> validate(ExecutableElement providesMethodElement) {
+    ValidationReport.Builder<ExecutableElement> builder =
+        ValidationReport.about(providesMethodElement);
+
+    Provides providesAnnotation = providesMethodElement.getAnnotation(Provides.class);
+    checkArgument(providesAnnotation != null);
+
+    Element enclosingElement = providesMethodElement.getEnclosingElement();
+    if (!isAnnotationPresent(enclosingElement, Module.class)) {
+      builder.addError(
+          formatModuleErrorMessage(BINDING_METHOD_NOT_IN_MODULE), providesMethodElement);
+    }
+
+    if (!providesMethodElement.getTypeParameters().isEmpty()) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_TYPE_PARAMETER), providesMethodElement);
+    }
+
+    Set<Modifier> modifiers = providesMethodElement.getModifiers();
+    if (modifiers.contains(PRIVATE)) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_PRIVATE), providesMethodElement);
+    }
+    if (modifiers.contains(ABSTRACT)) {
+      builder.addError(formatErrorMessage(BINDING_METHOD_ABSTRACT), providesMethodElement);
+    }
+
+    TypeMirror returnType = providesMethodElement.getReturnType();
+    TypeKind returnTypeKind = returnType.getKind();
+    if (returnTypeKind.equals(VOID)) {
+      builder.addError(
+          formatErrorMessage(BINDING_METHOD_MUST_RETURN_A_VALUE), providesMethodElement);
+    }
+
+    // check mapkey is right
+    if (!providesAnnotation.type().equals(Provides.Type.MAP)
+        && !getMapKeys(providesMethodElement).isEmpty()) {
+      builder.addError(
+          formatErrorMessage(BINDING_METHOD_NOT_MAP_HAS_MAP_KEY), providesMethodElement);
+    }
+
+    validateMethodQualifiers(builder, providesMethodElement);
+
+    switch (providesAnnotation.type()) {
+      case UNIQUE: // fall through
+      case SET:
+        validateKeyType(builder, returnType);
+        break;
+      case MAP:
+        validateKeyType(builder, returnType);
+        ImmutableSet<? extends AnnotationMirror> mapKeys = getMapKeys(providesMethodElement);
+        switch (mapKeys.size()) {
+          case 0:
+            builder.addError(
+                formatErrorMessage(BINDING_METHOD_WITH_NO_MAP_KEY), providesMethodElement);
+            break;
+          case 1:
+            break;
+          default:
+            builder.addError(
+                formatErrorMessage(BINDING_METHOD_WITH_MULTIPLE_MAP_KEY), providesMethodElement);
+            break;
+        }
+        break;
+      case SET_VALUES:
+        if (!returnTypeKind.equals(DECLARED)) {
+          builder.addError(PROVIDES_METHOD_SET_VALUES_RETURN_SET, providesMethodElement);
+        } else {
+          DeclaredType declaredReturnType = (DeclaredType) returnType;
+          // TODO(gak): should we allow "covariant return" for set values?
+          if (!declaredReturnType.asElement().equals(getSetElement())) {
+            builder.addError(PROVIDES_METHOD_SET_VALUES_RETURN_SET, providesMethodElement);
+          } else if (declaredReturnType.getTypeArguments().isEmpty()) {
+            builder.addError(
+                formatErrorMessage(BINDING_METHOD_SET_VALUES_RAW_SET), providesMethodElement);
+          } else {
+            validateKeyType(builder,
+                Iterables.getOnlyElement(declaredReturnType.getTypeArguments()));
+          }
+        }
+        break;
+      default:
+        throw new AssertionError();
+    }
+
+    return builder.build();
+  }
+
+  /** Validates that a Provides or Produces method doesn't have multiple qualifiers. */
+  static void validateMethodQualifiers(ValidationReport.Builder<ExecutableElement> builder,
+      ExecutableElement methodElement) {
+    ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(methodElement);
+    if (qualifiers.size() > 1) {
+      for (AnnotationMirror qualifier : qualifiers) {
+        builder.addError(PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS, methodElement, qualifier);
+      }
+    }
+  }
+
+  private String formatErrorMessage(String msg) {
+    return String.format(msg, Provides.class.getSimpleName());
+  }
+
+  private String formatModuleErrorMessage(String msg) {
+    return String.format(msg, Provides.class.getSimpleName(), Module.class.getSimpleName());
+  }
+
+  private void validateKeyType(ValidationReport.Builder<? extends Element> reportBuilder,
+      TypeMirror type) {
+    TypeKind kind = type.getKind();
+    if (!(kind.isPrimitive() || kind.equals(DECLARED) || kind.equals(ARRAY))) {
+      reportBuilder.addError(PROVIDES_METHOD_RETURN_TYPE, reportBuilder.getSubject());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ProvisionBinding.java b/compiler/src/main/java/dagger/internal/codegen/ProvisionBinding.java
new file mode 100644
index 0000000..b2ac74f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ProvisionBinding.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import dagger.Provides;
+import javax.inject.Inject;
+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.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.common.MoreTypes.asDeclared;
+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.getQualifier;
+import static dagger.internal.codegen.Scope.scopeOf;
+import static javax.lang.model.element.ElementKind.CONSTRUCTOR;
+import static javax.lang.model.element.ElementKind.FIELD;
+import static javax.lang.model.element.ElementKind.METHOD;
+
+/**
+ * A value object representing the mechanism by which a {@link Key} can be provided. New instances
+ * should be created using an instance of the {@link Factory}.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@AutoValue
+abstract class ProvisionBinding extends ContributionBinding {
+  
+  @Override
+  Binding.Type bindingType() {
+    return Binding.Type.PROVISION;
+  }
+  
+  @Override
+  abstract Scope scope();
+
+  static final class Factory {
+    private final Elements elements;
+    private final Types types;
+    private final Key.Factory keyFactory;
+    private final DependencyRequest.Factory dependencyRequestFactory;
+
+    Factory(Elements elements, Types types, Key.Factory keyFactory,
+        DependencyRequest.Factory dependencyRequestFactory) {
+      this.elements = elements;
+      this.types = types;
+      this.keyFactory = keyFactory;
+      this.dependencyRequestFactory = dependencyRequestFactory;
+    }
+
+    /** Returns an unresolved version of this binding. */
+    ProvisionBinding unresolve(ProvisionBinding binding) {
+      checkState(binding.hasNonDefaultTypeParameters());
+      return forInjectConstructor((ExecutableElement) binding.bindingElement(),
+          Optional.<TypeMirror>absent());
+    }
+
+    /**
+     * Returns a ProvisionBinding for the given element. If {@code resolvedType} is present, this
+     * will return a resolved binding, with the key & type resolved to the given type (using
+     * {@link Types#asMemberOf(DeclaredType, Element)}).
+     */
+    ProvisionBinding forInjectConstructor(ExecutableElement constructorElement,
+        Optional<TypeMirror> resolvedType) {
+      checkNotNull(constructorElement);
+      checkArgument(constructorElement.getKind().equals(CONSTRUCTOR));
+      checkArgument(isAnnotationPresent(constructorElement, Inject.class));
+      checkArgument(!getQualifier(constructorElement).isPresent());
+
+      ExecutableType cxtorType = MoreTypes.asExecutable(constructorElement.asType());
+      DeclaredType enclosingCxtorType =
+          MoreTypes.asDeclared(constructorElement.getEnclosingElement().asType());
+      // If the class this is constructing has some type arguments, resolve everything.
+      if (!enclosingCxtorType.getTypeArguments().isEmpty() && resolvedType.isPresent()) {
+        DeclaredType resolved = MoreTypes.asDeclared(resolvedType.get());
+        // Validate that we're resolving from the correct type.
+        checkState(types.isSameType(types.erasure(resolved), types.erasure(enclosingCxtorType)),
+            "erased expected type: %s, erased actual type: %s",
+            types.erasure(resolved), types.erasure(enclosingCxtorType));
+        cxtorType = MoreTypes.asExecutable(types.asMemberOf(resolved, constructorElement));
+        enclosingCxtorType = resolved;
+      }
+
+      Key key = keyFactory.forInjectConstructorWithResolvedType(enclosingCxtorType);
+      checkArgument(!key.qualifier().isPresent());
+      ImmutableSet<DependencyRequest> dependencies =
+          dependencyRequestFactory.forRequiredResolvedVariables(enclosingCxtorType,
+              constructorElement.getParameters(),
+              cxtorType.getParameterTypes());
+      Optional<DependencyRequest> membersInjectionRequest =
+          membersInjectionRequest(enclosingCxtorType);
+      Scope scope = Scope.scopeOf(constructorElement.getEnclosingElement());
+
+      TypeElement bindingTypeElement =
+          MoreElements.asType(constructorElement.getEnclosingElement());
+
+      return new AutoValue_ProvisionBinding(
+          key,
+          constructorElement,
+          dependencies,
+          findBindingPackage(key),
+          hasNonDefaultTypeParameters(bindingTypeElement, key.type(), types),
+          Optional.<DeclaredType>absent(),
+          Optional.<TypeElement>absent(),
+          membersInjectionRequest,
+          Kind.INJECTION,
+          Provides.Type.UNIQUE,
+          scope);
+    }
+
+    private static final ImmutableSet<ElementKind> MEMBER_KINDS =
+        Sets.immutableEnumSet(METHOD, FIELD);
+
+    private Optional<DependencyRequest> membersInjectionRequest(DeclaredType type) {
+      TypeElement typeElement = MoreElements.asType(type.asElement());
+      if (!types.isSameType(elements.getTypeElement(Object.class.getCanonicalName()).asType(),
+          typeElement.getSuperclass())) {
+        return Optional.of(dependencyRequestFactory.forMembersInjectedType(type));
+      }
+      for (Element enclosedElement : typeElement.getEnclosedElements()) {
+        if (MEMBER_KINDS.contains(enclosedElement.getKind())
+            && (isAnnotationPresent(enclosedElement, Inject.class))) {
+          return Optional.of(dependencyRequestFactory.forMembersInjectedType(type));
+        }
+      }
+      return Optional.absent();
+    }
+
+    ProvisionBinding forProvidesMethod(ExecutableElement providesMethod, TypeMirror contributedBy) {
+      checkNotNull(providesMethod);
+      checkArgument(providesMethod.getKind().equals(METHOD));
+      checkArgument(contributedBy.getKind().equals(TypeKind.DECLARED));
+      Provides providesAnnotation = providesMethod.getAnnotation(Provides.class);
+      checkArgument(providesAnnotation != null);
+      DeclaredType declaredContainer = MoreTypes.asDeclared(contributedBy);
+      ExecutableType resolvedMethod =
+          MoreTypes.asExecutable(types.asMemberOf(declaredContainer, providesMethod));
+      Key key = keyFactory.forProvidesMethod(resolvedMethod, providesMethod);
+      ImmutableSet<DependencyRequest> dependencies =
+          dependencyRequestFactory.forRequiredResolvedVariables(
+              declaredContainer,
+              providesMethod.getParameters(),
+              resolvedMethod.getParameterTypes());
+      Scope scope = Scope.scopeOf(providesMethod);
+      return new AutoValue_ProvisionBinding(
+          key,
+          providesMethod,
+          dependencies,
+          findBindingPackage(key),
+          false /* no non-default parameter types */,
+          ConfigurationAnnotations.getNullableType(providesMethod),
+          Optional.of(MoreTypes.asTypeElement(declaredContainer)),
+          Optional.<DependencyRequest>absent(),
+          Kind.PROVISION,
+          providesAnnotation.type(),
+          scope);
+    }
+
+    ProvisionBinding implicitMapOfProviderBinding(DependencyRequest mapOfValueRequest) {
+      checkNotNull(mapOfValueRequest);
+      Optional<Key> implicitMapOfProviderKey =
+          keyFactory.implicitMapProviderKeyFrom(mapOfValueRequest.key());
+      checkArgument(
+          implicitMapOfProviderKey.isPresent(),
+          "%s is not a request for Map<K, V>",
+          mapOfValueRequest);
+      DependencyRequest implicitMapOfProviderRequest =
+          dependencyRequestFactory.forImplicitMapBinding(
+              mapOfValueRequest, implicitMapOfProviderKey.get());
+      return new AutoValue_ProvisionBinding(
+          mapOfValueRequest.key(),
+          implicitMapOfProviderRequest.requestElement(),
+          ImmutableSet.of(implicitMapOfProviderRequest),
+          findBindingPackage(mapOfValueRequest.key()),
+          false /* no non-default parameter types */,
+          Optional.<DeclaredType>absent(),
+          Optional.<TypeElement>absent(),
+          Optional.<DependencyRequest>absent(),
+          Kind.SYNTHETIC,
+          Provides.Type.MAP,
+          scopeOf(implicitMapOfProviderRequest.requestElement()));
+    }
+
+    ProvisionBinding forComponent(TypeElement componentDefinitionType) {
+      checkNotNull(componentDefinitionType);
+      return new AutoValue_ProvisionBinding(
+          keyFactory.forComponent(componentDefinitionType.asType()),
+          componentDefinitionType,
+          ImmutableSet.<DependencyRequest>of(),
+          Optional.<String>absent(),
+          false /* no non-default parameter types */,
+          Optional.<DeclaredType>absent(),
+          Optional.<TypeElement>absent(),
+          Optional.<DependencyRequest>absent(),
+          Kind.COMPONENT,
+          Provides.Type.UNIQUE,
+          Scope.unscoped());
+    }
+
+    ProvisionBinding forComponentMethod(ExecutableElement componentMethod) {
+      checkNotNull(componentMethod);
+      checkArgument(componentMethod.getKind().equals(METHOD));
+      checkArgument(componentMethod.getParameters().isEmpty());
+      Scope scope = Scope.scopeOf(componentMethod);
+      return new AutoValue_ProvisionBinding(
+          keyFactory.forComponentMethod(componentMethod),
+          componentMethod,
+          ImmutableSet.<DependencyRequest>of(),
+          Optional.<String>absent(),
+          false /* no non-default parameter types */,
+          ConfigurationAnnotations.getNullableType(componentMethod),
+          Optional.<TypeElement>absent(),
+          Optional.<DependencyRequest>absent(),
+          Kind.COMPONENT_PROVISION,
+          Provides.Type.UNIQUE,
+          scope);
+    }
+
+    ProvisionBinding forSubcomponentBuilderMethod(
+        ExecutableElement subcomponentBuilderMethod, TypeElement contributedBy) {
+      checkNotNull(subcomponentBuilderMethod);
+      checkArgument(subcomponentBuilderMethod.getKind().equals(METHOD));
+      checkArgument(subcomponentBuilderMethod.getParameters().isEmpty());
+      DeclaredType declaredContainer = asDeclared(contributedBy.asType());
+      return new AutoValue_ProvisionBinding(
+          keyFactory.forSubcomponentBuilderMethod(subcomponentBuilderMethod, declaredContainer),
+          subcomponentBuilderMethod,
+          ImmutableSet.<DependencyRequest>of(),
+          Optional.<String>absent(),
+          false /* no non-default parameter types */,
+          Optional.<DeclaredType>absent(),
+          Optional.of(contributedBy),
+          Optional.<DependencyRequest>absent(),
+          Kind.SUBCOMPONENT_BUILDER,
+          Provides.Type.UNIQUE,
+          Scope.unscoped());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ResolvedBindings.java b/compiler/src/main/java/dagger/internal/codegen/ResolvedBindings.java
new file mode 100644
index 0000000..024097e
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ResolvedBindings.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static dagger.internal.codegen.ContributionBinding.contributionTypeFor;
+
+/**
+ * The collection of bindings that have been resolved for a binding key.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class ResolvedBindings {
+  /**
+   * The binding key for which the {@link #bindings()} have been resolved.
+   */
+  abstract BindingKey bindingKey();
+
+  /**
+   * The component in which the bindings in {@link #ownedBindings()},
+   * {@link #ownedContributionBindings()}, and {@link #ownedMembersInjectionBinding()} were
+   * resolved.
+   */
+  abstract ComponentDescriptor owningComponent();
+
+  /**
+   * The contribution bindings for {@link #bindingKey()} that were resolved in
+   * {@link #owningComponent()} or its ancestor components, keyed by the component in which the
+   * binding was resolved. If {@link #bindingKey()}'s kind is not
+   * {@link BindingKey.Kind#CONTRIBUTION}, this is empty.
+   */
+  abstract ImmutableSetMultimap<ComponentDescriptor, ContributionBinding> allContributionBindings();
+
+  /**
+   * The members-injection bindings for {@link #bindingKey()} that were resolved in
+   * {@link #owningComponent()} or its ancestor components, keyed by the component in which the
+   * binding was resolved. If {@link #bindingKey()}'s kind is not
+   * {@link BindingKey.Kind#MEMBERS_INJECTION}, this is empty.
+   */
+  abstract ImmutableMap<ComponentDescriptor, MembersInjectionBinding> allMembersInjectionBindings();
+
+  /**
+   * All bindings for {@link #bindingKey()}, regardless of in which component they were resolved.
+   */
+  ImmutableSet<? extends Binding> bindings() {
+    switch (bindingKey().kind()) {
+      case CONTRIBUTION:
+        return contributionBindings();
+
+      case MEMBERS_INJECTION:
+        return ImmutableSet.copyOf(membersInjectionBinding().asSet());
+
+      default:
+        throw new AssertionError(bindingKey());
+    }
+  }
+
+  /**
+   * All bindings for {@link #bindingKey()} that were resolved in {@link #owningComponent()}.
+   */
+  ImmutableSet<? extends Binding> ownedBindings() {
+    switch (bindingKey().kind()) {
+      case CONTRIBUTION:
+        return ownedContributionBindings();
+
+      case MEMBERS_INJECTION:
+        return ImmutableSet.copyOf(ownedMembersInjectionBinding().asSet());
+
+      default:
+        throw new AssertionError(bindingKey());
+    }
+  }
+
+  /**
+   * All contribution bindings, regardless of owning component.
+   *
+   * @throws IllegalStateException if {@link #bindingKey()} is not a
+   * {@link BindingKey.Kind#CONTRIBUTION}.
+   */
+  ImmutableSet<ContributionBinding> contributionBindings() {
+    checkState(bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION));
+    return ImmutableSet.copyOf(allContributionBindings().values());
+  }
+
+  /**
+   * The contribution bindings that were resolved in {@link #owningComponent()}.
+   *
+   * @throws IllegalStateException if {@link #bindingKey()} is not a
+   * {@link BindingKey.Kind#CONTRIBUTION}.
+   */
+  ImmutableSet<ContributionBinding> ownedContributionBindings() {
+    checkState(bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION));
+    return allContributionBindings().get(owningComponent());
+  }
+
+  /**
+   * The members-injection binding, regardless of owning component.
+   *
+   * @throws IllegalStateException if {@link #bindingKey()} is not a
+   * {@link BindingKey.Kind#MEMBERS_INJECTION}.
+   */
+  Optional<MembersInjectionBinding> membersInjectionBinding() {
+    checkState(bindingKey().kind().equals(BindingKey.Kind.MEMBERS_INJECTION));
+    ImmutableSet<MembersInjectionBinding> membersInjectionBindings =
+        FluentIterable.from(allMembersInjectionBindings().values()).toSet();
+    return membersInjectionBindings.isEmpty()
+        ? Optional.<MembersInjectionBinding>absent()
+        : Optional.of(Iterables.getOnlyElement(membersInjectionBindings));
+  }
+
+  /**
+   * The members-injection binding that was resolved in {@link #owningComponent()}.
+   *
+   * @throws IllegalStateException if {@link #bindingKey()} is not a
+   * {@link BindingKey.Kind#MEMBERS_INJECTION}.
+   */
+  Optional<MembersInjectionBinding> ownedMembersInjectionBinding() {
+    checkState(bindingKey().kind().equals(BindingKey.Kind.MEMBERS_INJECTION));
+    return Optional.fromNullable(allMembersInjectionBindings().get(owningComponent()));
+  }
+
+  /**
+   * Creates a {@link ResolvedBindings} for contribution bindings.
+   */
+  static ResolvedBindings forContributionBindings(
+      BindingKey bindingKey,
+      ComponentDescriptor owningComponent,
+      Multimap<ComponentDescriptor, ? extends ContributionBinding> contributionBindings) {
+    checkArgument(bindingKey.kind().equals(BindingKey.Kind.CONTRIBUTION));
+    return new AutoValue_ResolvedBindings(
+        bindingKey,
+        owningComponent,
+        ImmutableSetMultimap.<ComponentDescriptor, ContributionBinding>copyOf(contributionBindings),
+        ImmutableMap.<ComponentDescriptor, MembersInjectionBinding>of());
+  }
+
+  /**
+   * Creates a {@link ResolvedBindings} for contribution bindings.
+   */
+  static ResolvedBindings forContributionBindings(
+      BindingKey bindingKey,
+      ComponentDescriptor owningComponent,
+      ContributionBinding... ownedContributionBindings) {
+    return forContributionBindings(
+        bindingKey,
+        owningComponent,
+        ImmutableSetMultimap.<ComponentDescriptor, ContributionBinding>builder()
+            .putAll(owningComponent, ownedContributionBindings)
+            .build());
+  }
+
+  /**
+   * Creates a {@link ResolvedBindings} for members injection bindings.
+   */
+  static ResolvedBindings forMembersInjectionBinding(
+      BindingKey bindingKey,
+      ComponentDescriptor owningComponent,
+      MembersInjectionBinding ownedMembersInjectionBinding) {
+    checkArgument(bindingKey.kind().equals(BindingKey.Kind.MEMBERS_INJECTION));
+    return new AutoValue_ResolvedBindings(
+        bindingKey,
+        owningComponent,
+        ImmutableSetMultimap.<ComponentDescriptor, ContributionBinding>of(),
+        ImmutableMap.of(owningComponent, ownedMembersInjectionBinding));
+  }
+
+  /**
+   * Creates a {@link ResolvedBindings} appropriate for when there are no bindings for the key.
+   */
+  static ResolvedBindings noBindings(BindingKey bindingKey, ComponentDescriptor owningComponent) {
+    return new AutoValue_ResolvedBindings(
+        bindingKey,
+        owningComponent,
+        ImmutableSetMultimap.<ComponentDescriptor, ContributionBinding>of(),
+        ImmutableMap.<ComponentDescriptor, MembersInjectionBinding>of());
+  }
+
+  /**
+   * Returns a {@code ResolvedBindings} with the same {@link #bindingKey()} and {@link #bindings()}
+   * as this one, but no {@link #ownedBindings()}.
+   */
+  ResolvedBindings asInheritedIn(ComponentDescriptor owningComponent) {
+    return new AutoValue_ResolvedBindings(
+        bindingKey(), owningComponent, allContributionBindings(), allMembersInjectionBindings());
+  }
+
+  /**
+   * {@code true} if this is a multibindings contribution.
+   */
+  boolean isMultibindings() {
+    return bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION)
+        && !contributionBindings().isEmpty()
+        && contributionTypeFor(contributionBindings()).isMultibinding();
+  }
+
+  /**
+   * {@code true} if this is a unique contribution binding.
+   */
+  boolean isUniqueContribution() {
+    return bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION)
+        && !contributionBindings().isEmpty()
+        && !contributionTypeFor(contributionBindings()).isMultibinding();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/Scope.java b/compiler/src/main/java/dagger/internal/codegen/Scope.java
new file mode 100644
index 0000000..bcb009d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/Scope.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.AnnotationMirrors;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nullable;
+import javax.inject.Singleton;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import static com.google.auto.common.MoreTypes.isTypeOf;
+import static dagger.internal.codegen.ErrorMessages.stripCommonTypePrefixes;
+import static dagger.internal.codegen.InjectionAnnotations.getScopeAnnotation;
+
+/**
+ * A representation of the scope (or lack of it) associated with a component, providing method
+ * or injection location.
+ */
+final class Scope {
+
+  /**
+   * An internal representation for an unscoped binding.
+   */
+  private static final Scope UNSCOPED = new Scope();
+
+  /**
+   * The underlying {@link AnnotationMirror} that represents the scope annotation.
+   */
+  @Nullable
+  private final AnnotationMirror annotationMirror;
+
+  private Scope(@Nullable AnnotationMirror annotationMirror) {
+    this.annotationMirror = annotationMirror;
+  }
+
+  private Scope() {
+    this(null);
+  }
+
+  /**
+   * Returns representation for an unscoped binding.
+   */
+  static Scope unscoped() {
+    return UNSCOPED;
+  }
+
+  /**
+   * If the source code element has an associated scoped annotation then returns a representation
+   * of that scope, otherwise returns a representation for an unscoped binding.
+   */
+  static Scope scopeOf(Element element) {
+    Optional<AnnotationMirror> scopeAnnotation = getScopeAnnotation(element);
+    return scopeAnnotation.isPresent() ? new Scope(scopeAnnotation.get()) : UNSCOPED;
+  }
+
+  /**
+   * Returns true if the scope is present, i.e. it's not unscoped binding.
+   */
+  public boolean isPresent() {
+    return annotationMirror != null;
+  }
+
+  /**
+   * Returns true if the scope represents the {@link Singleton @Singleton} annotation.
+   */
+  public boolean isSingleton() {
+    return annotationMirror != null
+        && isTypeOf(Singleton.class, annotationMirror.getAnnotationType());
+  }
+
+  /**
+   * Returns the readable source representation (name with @ prefix) of the annotation type.
+   *
+   * <p>It's readable source because it has had common package prefixes removed, e.g.
+   * {@code @javax.inject.Singleton} is returned as {@code @Singleton}.
+   *
+   * <p>Make sure that the scope is actually {@link #isPresent() present} before calling as it will
+   * throw an {@link IllegalStateException} otherwise. This does not return any annotation values
+   * as according to {@link javax.inject.Scope} scope annotations are not supposed to use them.
+   */
+  public String getReadableSource() {
+    return stripCommonTypePrefixes("@" + getQualifiedName());
+  }
+
+  /**
+   * Returns the fully qualified name of the annotation type.
+   *
+   * <p>Make sure that the scope is actually {@link #isPresent() present} before calling as it will
+   * throw an {@link IllegalStateException} otherwise. This does not return any annotation values
+   * as according to {@link javax.inject.Scope} scope annotations are not supposed to use them.
+   */
+  public String getQualifiedName() {
+    Preconditions.checkState(annotationMirror != null,
+        "Cannot create a stripped source representation of no annotation");
+    TypeElement typeElement = MoreTypes.asTypeElement(annotationMirror.getAnnotationType());
+    return typeElement.getQualifiedName().toString();
+  }
+
+  /**
+   * Scopes are equal if the underlying {@link AnnotationMirror} are equivalent according to
+   * {@link AnnotationMirrors#equivalence()}.
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    } else if (obj instanceof Scope) {
+      Scope that = (Scope) obj;
+      return AnnotationMirrors.equivalence()
+        .equivalent(this.annotationMirror, that.annotationMirror);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return AnnotationMirrors.equivalence().hash(annotationMirror);
+  }
+
+  /**
+   * Returns a debug representation of the scope.
+   */
+  @Override
+  public String toString() {
+    return annotationMirror == null ? "UNSCOPED" : annotationMirror.toString();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerationException.java b/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerationException.java
new file mode 100644
index 0000000..c262098
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerationException.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import dagger.internal.codegen.writer.ClassName;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+/**
+ * An exception thrown to indicate that a source file could not be generated.
+ *
+ * <p>This exception <b>should not</b> be used to report detectable, logical errors as it may mask
+ * other errors that might have been caught upon further processing.  Use a {@link ValidationReport}
+ * for that.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+final class SourceFileGenerationException extends Exception {
+  private final ImmutableSet<ClassName> generatedClassNames;
+  private final Optional<? extends Element> associatedElement;
+
+  SourceFileGenerationException(Iterable<ClassName> generatedClassNames, Throwable cause,
+      Optional<? extends Element> associatedElement) {
+    super(createMessage(generatedClassNames, cause.getMessage()), cause);
+    this.generatedClassNames = ImmutableSet.copyOf(generatedClassNames);
+    this.associatedElement = checkNotNull(associatedElement);
+  }
+
+  SourceFileGenerationException(Iterable<ClassName> generatedClassNames, Throwable cause) {
+    this(generatedClassNames, cause, Optional.<Element>absent());
+  }
+
+  SourceFileGenerationException(Iterable<ClassName> generatedClassNames, Throwable cause,
+      Element associatedElement) {
+    this(generatedClassNames, cause, Optional.of(associatedElement));
+  }
+
+  public ImmutableSet<ClassName> generatedClassNames() {
+    return generatedClassNames;
+  }
+
+  public Optional<? extends Element> associatedElement() {
+    return associatedElement;
+  }
+
+  private static String createMessage(Iterable<ClassName> generatedClassNames, String message) {
+    return String.format("Could not generate %s: %s.",
+        Iterables.isEmpty(generatedClassNames)
+            ? "unknown files"
+            : Iterables.toString(generatedClassNames),
+        message);
+  }
+
+  void printMessageTo(Messager messager) {
+    if (associatedElement.isPresent()) {
+      messager.printMessage(ERROR, getMessage(), associatedElement.get());
+    } else {
+      messager.printMessage(ERROR, getMessage());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerator.java b/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerator.java
new file mode 100644
index 0000000..4b6efc0
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/SourceFileGenerator.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.JavaWriter;
+import dagger.internal.codegen.writer.TypeWriter;
+import java.io.IOException;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A template class that provides a framework for properly handling IO while generating source files
+ * from an annotation processor.  Particularly, it makes a best effort to ensure that files that
+ * fail to write successfully are deleted.
+ *
+ * @param <T> The input type from which source is to be generated.
+ * @author Gregory Kick
+ * @since 2.0
+ */
+abstract class SourceFileGenerator<T> {
+  private final Filer filer;
+
+  SourceFileGenerator(Filer filer) {
+    this.filer = checkNotNull(filer);
+  }
+
+  final void generate(T input) throws SourceFileGenerationException {
+    ClassName generatedTypeName = nameGeneratedType(input);
+    ImmutableSet<Element> originatingElements =
+        ImmutableSet.<Element>copyOf(getOriginatingElements(input));
+    try {
+      ImmutableSet<JavaWriter> writers = write(generatedTypeName, input);
+      for (JavaWriter javaWriter : writers) {
+        try {
+          javaWriter.file(filer, originatingElements);
+        } catch (IOException e) {
+          throw new SourceFileGenerationException(getNamesForWriters(javaWriter.getTypeWriters()),
+              e, getElementForErrorReporting(input));
+        }
+      }
+    } catch (Exception e) {
+      // if the code above threw a SFGE, use that
+      Throwables.propagateIfPossible(e, SourceFileGenerationException.class);
+      // otherwise, throw a new one
+      throw new SourceFileGenerationException(ImmutableList.<ClassName>of(), e,
+          getElementForErrorReporting(input));
+    }
+  }
+
+  private static Iterable<ClassName> getNamesForWriters(Iterable<TypeWriter> typeWriters) {
+    return Iterables.transform(typeWriters, new Function<TypeWriter, ClassName>() {
+      @Override public ClassName apply(TypeWriter input) {
+        return input.name();
+      }
+    });
+  }
+
+  /**
+   * Implementations should return the {@link ClassName} for the top-level type to be generated.
+   */
+  abstract ClassName nameGeneratedType(T input);
+
+  /**
+   * Implementations should return {@link Element} instances from which the source is to be
+   * generated.
+   */
+  abstract Iterable<? extends Element> getOriginatingElements(T input);
+
+  /**
+   * Returns an optional element to be used for reporting errors. This returns a single element
+   * rather than a collection to reduce output noise.
+   */
+  abstract Optional<? extends Element> getElementForErrorReporting(T input);
+
+  /**
+   */
+  abstract ImmutableSet<JavaWriter> write(ClassName generatedTypeName, T input);
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/SourceFiles.java b/compiler/src/main/java/dagger/internal/codegen/SourceFiles.java
new file mode 100644
index 0000000..7ad0acb
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/SourceFiles.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.CaseFormat;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Ordering;
+import dagger.internal.DoubleCheckLazy;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Utilities for generating files.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+class SourceFiles {
+  /**
+   * Sorts {@link DependencyRequest} instances in an order likely to reflect their logical
+   * importance.
+   */
+  static final Ordering<DependencyRequest> DEPENDENCY_ORDERING = new Ordering<DependencyRequest>() {
+    @Override
+    public int compare(DependencyRequest left, DependencyRequest right) {
+      return ComparisonChain.start()
+      // put fields before parameters
+          .compare(left.requestElement().getKind(), right.requestElement().getKind())
+          // order by dependency kind
+          .compare(left.kind(), right.kind())
+          // then sort by name
+          .compare(left.requestElement().getSimpleName().toString(),
+              right.requestElement().getSimpleName().toString()).result();
+    }
+  };
+
+  /**
+   * A variant of {@link #indexDependenciesByKey} that maps from unresolved keys
+   * to requests.  This is used when generating component's initialize()
+   * methods (and in members injectors) in order to instantiate dependent
+   * providers.  Consider a generic type of {@code Foo<T>} with a constructor
+   * of {@code Foo(T t, T t1, A a, A a1)}.  That will be collapsed to a factory
+   * taking a {@code Provider<T> tProvider, Provider<A> aProvider}. However,
+   * if it was referenced as {@code Foo<A>}, we need to make sure we still
+   * pass two providers.  Naively (if we just referenced by resolved BindingKey),
+   * we would have passed a single {@code aProvider}.
+   */
+  // TODO(user): Refactor these indexing methods so that the binding itself knows what sort of
+  // binding keys and framework classes that it needs.
+  static ImmutableSetMultimap<BindingKey, DependencyRequest> indexDependenciesByUnresolvedKey(
+      Types types, Iterable<? extends DependencyRequest> dependencies) {
+    ImmutableSetMultimap.Builder<BindingKey, DependencyRequest> dependenciesByKeyBuilder =
+        new ImmutableSetMultimap.Builder<BindingKey, DependencyRequest>()
+            .orderValuesBy(DEPENDENCY_ORDERING);
+    for (DependencyRequest dependency : dependencies) {
+      BindingKey resolved = dependency.bindingKey();
+      // To get the proper unresolved type, we have to extract the proper type from the
+      // request type again (because we're looking at the actual element's type).
+      TypeMirror unresolvedType =
+          DependencyRequest.Factory.extractKindAndType(dependency.requestElement().asType()).type();
+      BindingKey unresolved =
+          BindingKey.create(resolved.kind(), resolved.key().withType(types, unresolvedType));
+      dependenciesByKeyBuilder.put(unresolved, dependency);
+    }
+    return dependenciesByKeyBuilder.build();
+  }
+
+  /**
+   * Allows dependency requests to be grouped by the key they're requesting.
+   * This is used by factory generation in order to minimize the number of parameters
+   * required in the case where a given key is requested more than once.  This expects
+   * unresolved dependency requests, otherwise we may generate factories based on
+   * a particular usage of a class as opposed to the generic types of the class.
+   */
+  static ImmutableSetMultimap<BindingKey, DependencyRequest> indexDependenciesByKey(
+      Iterable<? extends DependencyRequest> dependencies) {
+    ImmutableSetMultimap.Builder<BindingKey, DependencyRequest> dependenciesByKeyBuilder =
+        new ImmutableSetMultimap.Builder<BindingKey, DependencyRequest>()
+            .orderValuesBy(DEPENDENCY_ORDERING);
+    for (DependencyRequest dependency : dependencies) {
+      dependenciesByKeyBuilder.put(dependency.bindingKey(), dependency);
+    }
+    return dependenciesByKeyBuilder.build();
+  }
+
+  /**
+   * This method generates names and keys for the framework classes necessary for all of the
+   * bindings. It is responsible for the following:
+   * <ul>
+   * <li>Choosing a name that associates the binding with all of the dependency requests for this
+   * type.
+   * <li>Choosing a name that is <i>probably</i> associated with the type being bound.
+   * <li>Ensuring that no two bindings end up with the same name.
+   * </ul>
+   *
+   * @return Returns the mapping from {@link BindingKey} to field, sorted by the name of the field.
+   */
+  static ImmutableMap<BindingKey, FrameworkField> generateBindingFieldsForDependencies(
+      DependencyRequestMapper dependencyRequestMapper,
+      Iterable<? extends DependencyRequest> dependencies) {
+    ImmutableSetMultimap<BindingKey, DependencyRequest> dependenciesByKey =
+        indexDependenciesByKey(dependencies);
+    Map<BindingKey, Collection<DependencyRequest>> dependenciesByKeyMap =
+        dependenciesByKey.asMap();
+    ImmutableMap.Builder<BindingKey, FrameworkField> bindingFields = ImmutableMap.builder();
+    for (Entry<BindingKey, Collection<DependencyRequest>> entry
+        : dependenciesByKeyMap.entrySet()) {
+      BindingKey bindingKey = entry.getKey();
+      Collection<DependencyRequest> requests = entry.getValue();
+      Class<?> frameworkClass =
+          dependencyRequestMapper.getFrameworkClass(requests.iterator().next());
+      // collect together all of the names that we would want to call the provider
+      ImmutableSet<String> dependencyNames =
+          FluentIterable.from(requests).transform(new DependencyVariableNamer()).toSet();
+
+      if (dependencyNames.size() == 1) {
+        // if there's only one name, great! use it!
+        String name = Iterables.getOnlyElement(dependencyNames);
+        bindingFields.put(bindingKey,
+            FrameworkField.createWithTypeFromKey(frameworkClass, bindingKey, name));
+      } else {
+        // in the event that a field is being used for a bunch of deps with different names,
+        // add all the names together with "And"s in the middle. E.g.: stringAndS
+        Iterator<String> namesIterator = dependencyNames.iterator();
+        String first = namesIterator.next();
+        StringBuilder compositeNameBuilder = new StringBuilder(first);
+        while (namesIterator.hasNext()) {
+          compositeNameBuilder.append("And").append(
+              CaseFormat.LOWER_CAMEL.to(UPPER_CAMEL, namesIterator.next()));
+        }
+        bindingFields.put(bindingKey, FrameworkField.createWithTypeFromKey(
+            frameworkClass, bindingKey, compositeNameBuilder.toString()));
+      }
+    }
+    return bindingFields.build();
+  }
+
+  static Snippet frameworkTypeUsageStatement(Snippet frameworkTypeMemberSelect,
+      DependencyRequest.Kind dependencyKind) {
+    switch (dependencyKind) {
+      case LAZY:
+        return Snippet.format("%s.create(%s)", ClassName.fromClass(DoubleCheckLazy.class),
+            frameworkTypeMemberSelect);
+      case INSTANCE:
+      case FUTURE:
+        return Snippet.format("%s.get()", frameworkTypeMemberSelect);
+      case PROVIDER:
+      case PRODUCER:
+      case MEMBERS_INJECTOR:
+        return Snippet.format("%s", frameworkTypeMemberSelect);
+      default:
+        throw new AssertionError();
+    }
+  }
+  
+  /**
+   * Returns the generated factory or members injector name for a binding.
+   */
+  static ClassName generatedClassNameForBinding(Binding binding) {
+    switch (binding.bindingType()) {
+      case PROVISION:
+      case PRODUCTION:
+        ContributionBinding contribution = (ContributionBinding) binding;
+        checkArgument(!contribution.isSyntheticBinding());
+        ClassName enclosingClassName = ClassName.fromTypeElement(contribution.bindingTypeElement());
+        switch (contribution.bindingKind()) {
+          case INJECTION:
+          case PROVISION:
+          case IMMEDIATE:
+          case FUTURE_PRODUCTION:
+            return enclosingClassName
+                .topLevelClassName()
+                .peerNamed(
+                    enclosingClassName.classFileName()
+                        + "_"
+                        + factoryPrefix(contribution)
+                        + "Factory");
+
+          default:
+            throw new AssertionError();
+        }
+
+      case MEMBERS_INJECTION:
+        return membersInjectorNameForType(binding.bindingTypeElement());
+
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  /**
+   * Returns the generated factory or members injector name parameterized with the proper type
+   * parameters if necessary.
+   */
+  static TypeName parameterizedGeneratedTypeNameForBinding(Binding binding) {
+    return generatedClassNameForBinding(binding).withTypeParameters(bindingTypeParameters(binding));
+  }
+  
+  private static ImmutableList<TypeName> bindingTypeParameters(Binding binding)
+      throws AssertionError {
+    TypeMirror bindingType;
+    switch (binding.bindingType()) {
+      case PROVISION:
+      case PRODUCTION:
+        ContributionBinding contributionBinding = (ContributionBinding) binding;
+        if (contributionBinding.contributionType().isMultibinding()) {
+          return ImmutableList.of();
+        }
+        switch (contributionBinding.bindingKind()) {
+          case INJECTION:
+            bindingType = contributionBinding.key().type();
+            break;
+            
+          case PROVISION:
+            // For provision bindings, we parameterize creation on the types of
+            // the module, not the types of the binding.
+            // Consider: Module<A, B, C> { @Provides List<B> provideB(B b) { .. }}
+            // The binding is just parameterized on <B>, but we need all of <A, B, C>.
+            bindingType = contributionBinding.bindingTypeElement().asType();
+            break;
+            
+          case IMMEDIATE:
+          case FUTURE_PRODUCTION:
+            // TODO(beder): Can these be treated just like PROVISION?
+            throw new UnsupportedOperationException();
+            
+          default:
+            return ImmutableList.of();
+        }
+        break;
+
+      case MEMBERS_INJECTION:
+        bindingType = binding.key().type();
+        break;
+
+      default:
+        throw new AssertionError();
+    }
+    TypeName bindingTypeName = TypeNames.forTypeMirror(bindingType);
+    return bindingTypeName instanceof ParameterizedTypeName
+        ? ((ParameterizedTypeName) bindingTypeName).parameters()
+        : ImmutableList.<TypeName>of();
+  }
+  
+  static ClassName membersInjectorNameForType(TypeElement typeElement) {
+    ClassName injectedClassName = ClassName.fromTypeElement(typeElement);
+    return injectedClassName
+        .topLevelClassName()
+        .peerNamed(injectedClassName.classFileName() + "_MembersInjector");
+  }
+
+  static ClassName generatedMonitoringModuleName(TypeElement componentElement) {
+    ClassName componentName = ClassName.fromTypeElement(componentElement);
+    return componentName
+        .topLevelClassName()
+        .peerNamed(componentName.classFileName() + "_MonitoringModule");
+  }
+
+  private static String factoryPrefix(ContributionBinding binding) {
+    switch (binding.bindingKind()) {
+      case INJECTION:
+        return "";
+
+      case PROVISION:
+      case IMMEDIATE:
+      case FUTURE_PRODUCTION:
+        return CaseFormat.LOWER_CAMEL.to(
+            UPPER_CAMEL, ((ExecutableElement) binding.bindingElement()).getSimpleName().toString());
+
+      default:
+        throw new IllegalArgumentException();
+    }
+  }
+
+  private SourceFiles() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/SubcomponentWriter.java b/compiler/src/main/java/dagger/internal/codegen/SubcomponentWriter.java
new file mode 100644
index 0000000..1287668
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/SubcomponentWriter.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import dagger.internal.codegen.ComponentDescriptor.BuilderSpec;
+import dagger.internal.codegen.ComponentGenerator.MemberSelect;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ClassWriter;
+import dagger.internal.codegen.writer.FieldWriter;
+import dagger.internal.codegen.writer.MethodWriter;
+import dagger.internal.codegen.writer.Snippet;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+
+import static com.google.common.base.CaseFormat.LOWER_CAMEL;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.collect.Sets.difference;
+import static dagger.internal.codegen.AbstractComponentWriter.InitializationState.UNINITIALIZED;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+/**
+ * Creates the nested implementation class for a subcomponent.
+ */
+class SubcomponentWriter extends AbstractComponentWriter {
+
+  private AbstractComponentWriter parent;
+  private ExecutableElement subcomponentFactoryMethod;
+
+  public SubcomponentWriter(
+      AbstractComponentWriter parent,
+      ExecutableElement subcomponentFactoryMethod,
+      BindingGraph subgraph) {
+    super(
+        parent.types,
+        parent.elements,
+        parent.keyFactory,
+        parent.nullableValidationType,
+        parent.name.nestedClassNamed(subcomponentSimpleName(subgraph)),
+        subgraph);
+    this.parent = parent;
+    this.subcomponentFactoryMethod = subcomponentFactoryMethod;
+  }
+
+  private static String subcomponentSimpleName(BindingGraph subgraph) {
+    return subgraph.componentDescriptor().componentDefinitionType().getSimpleName() + "Impl";
+  }
+  
+  @Override
+  protected InitializationState getInitializationState(BindingKey bindingKey) {
+    InitializationState initializationState = super.getInitializationState(bindingKey);
+    return initializationState.equals(UNINITIALIZED)
+        ? parent.getInitializationState(bindingKey)
+        : initializationState;
+  }
+
+  @Override
+  protected Optional<Snippet> getOrCreateComponentContributionFieldSnippet(
+      TypeElement contributionType) {
+    return super.getOrCreateComponentContributionFieldSnippet(contributionType)
+        .or(parent.getOrCreateComponentContributionFieldSnippet(contributionType));
+  }
+
+  @Override
+  protected MemberSelect getMemberSelect(BindingKey key) {
+    MemberSelect memberSelect = super.getMemberSelect(key);
+    return memberSelect == null ? parent.getMemberSelect(key) : memberSelect;
+  }
+
+  @Override
+  protected Optional<MemberSelect> getMultibindingContributionSnippet(ContributionBinding binding) {
+    return super.getMultibindingContributionSnippet(binding)
+        .or(parent.getMultibindingContributionSnippet(binding));
+  }
+
+  private ExecutableType resolvedSubcomponentFactoryMethod() {
+    return MoreTypes.asExecutable(
+        types.asMemberOf(
+            MoreTypes.asDeclared(parent.componentDefinitionType().asType()),
+            subcomponentFactoryMethod));
+  }
+
+  @Override
+  protected ClassWriter createComponentClass() {
+    ClassWriter componentWriter = parent.componentWriter.addNestedClass(name.simpleName());
+    componentWriter.addModifiers(PRIVATE, FINAL);
+    componentWriter.setSupertype(
+        MoreTypes.asTypeElement(
+            graph.componentDescriptor().builderSpec().isPresent()
+                ? graph
+                    .componentDescriptor()
+                    .builderSpec()
+                    .get()
+                    .componentType()
+                : resolvedSubcomponentFactoryMethod().getReturnType()));
+    return componentWriter;
+  }
+
+  @Override
+  protected void addBuilder() {
+    // Only write subcomponent builders if there is a spec.
+    if (graph.componentDescriptor().builderSpec().isPresent()) {
+      super.addBuilder();
+    }
+  }
+
+  @Override
+  protected ClassWriter createBuilder() {
+    // Only write subcomponent builders if there is a spec.
+    verify(graph.componentDescriptor().builderSpec().isPresent());
+    return parent.componentWriter.addNestedClass(
+        componentDefinitionTypeName().simpleName() + "Builder");
+  }
+
+  @Override
+  protected void addFactoryMethods() {
+    MethodWriter componentMethod;
+    if (graph.componentDescriptor().builderSpec().isPresent()) {
+      BuilderSpec spec = graph.componentDescriptor().builderSpec().get();
+      componentMethod =
+          parent.componentWriter.addMethod(
+              spec.builderDefinitionType().asType(),
+              subcomponentFactoryMethod.getSimpleName().toString());
+      componentMethod.body().addSnippet("return new %s();", builderName.get());
+    } else {
+      ExecutableType resolvedMethod = resolvedSubcomponentFactoryMethod();
+      componentMethod =
+          parent.componentWriter.addMethod(
+              resolvedMethod.getReturnType(), subcomponentFactoryMethod.getSimpleName().toString());
+      writeSubcomponentWithoutBuilder(componentMethod, resolvedMethod);
+    }
+    componentMethod.addModifiers(PUBLIC);
+    componentMethod.annotate(Override.class);
+  }
+
+  private void writeSubcomponentWithoutBuilder(
+      MethodWriter componentMethod, ExecutableType resolvedMethod) {
+    ImmutableList.Builder<Snippet> subcomponentConstructorParameters = ImmutableList.builder();
+    List<? extends VariableElement> params = subcomponentFactoryMethod.getParameters();
+    List<? extends TypeMirror> paramTypes = resolvedMethod.getParameterTypes();
+    for (int i = 0; i < params.size(); i++) {
+      VariableElement moduleVariable = params.get(i);
+      TypeElement moduleTypeElement = MoreTypes.asTypeElement(paramTypes.get(i));
+      TypeName moduleType = TypeNames.forTypeMirror(paramTypes.get(i));
+      componentMethod.addParameter(moduleType, moduleVariable.getSimpleName().toString());
+      if (!componentContributionFields.containsKey(moduleTypeElement)) {
+        String preferredModuleName =
+            CaseFormat.UPPER_CAMEL.to(LOWER_CAMEL, moduleTypeElement.getSimpleName().toString());
+        FieldWriter contributionField =
+            componentWriter.addField(moduleTypeElement, preferredModuleName);
+        contributionField.addModifiers(PRIVATE, FINAL);
+        String actualModuleName = contributionField.name();
+        constructorWriter.addParameter(moduleType, actualModuleName);
+        constructorWriter.body()
+            .addSnippet("if (%s == null) {", actualModuleName)
+            .addSnippet("  throw new NullPointerException();")
+            .addSnippet("}");
+        constructorWriter.body().addSnippet("this.%1$s = %1$s;", actualModuleName);
+        MemberSelect moduleSelect =
+            MemberSelect.instanceSelect(name, Snippet.format(actualModuleName));
+        componentContributionFields.put(moduleTypeElement, moduleSelect);
+        subcomponentConstructorParameters.add(Snippet.format("%s", moduleVariable.getSimpleName()));
+      }
+    }
+
+    Set<TypeElement> uninitializedModules =
+        difference(graph.componentRequirements(), componentContributionFields.keySet());
+    
+    for (TypeElement moduleType : uninitializedModules) {
+      String preferredModuleName =
+          CaseFormat.UPPER_CAMEL.to(LOWER_CAMEL, moduleType.getSimpleName().toString());
+      FieldWriter contributionField = componentWriter.addField(moduleType, preferredModuleName);
+      contributionField.addModifiers(PRIVATE, FINAL);
+      String actualModuleName = contributionField.name();
+      constructorWriter.body().addSnippet("this.%s = new %s();",
+          actualModuleName, ClassName.fromTypeElement(moduleType));
+      MemberSelect moduleSelect =
+          MemberSelect.instanceSelect(name, Snippet.format(actualModuleName));
+      componentContributionFields.put(moduleType, moduleSelect);
+    }
+
+    componentMethod.body().addSnippet("return new %s(%s);",
+        name, Snippet.makeParametersSnippet(subcomponentConstructorParameters.build()));
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/Util.java b/compiler/src/main/java/dagger/internal/codegen/Util.java
new file mode 100644
index 0000000..8c1aba3
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/Util.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import dagger.producers.Produced;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+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 static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
+import static com.google.auto.common.MoreTypes.asDeclared;
+import static com.google.common.base.Preconditions.checkState;
+import static javax.lang.model.element.ElementKind.CONSTRUCTOR;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+/**
+ * Utilities for handling types in annotation processors
+ */
+final class Util {
+  /**
+   * Returns the {@code V} type for a {@link Map} type like {@code Map<K, Provider<V>>} if the map
+   * includes such a construction
+   */
+  public static TypeMirror getProvidedValueTypeOfMap(DeclaredType mapType) {
+    checkState(MoreTypes.isTypeOf(Map.class, mapType), "%s is not a Map.", mapType);
+    return asDeclared(mapType.getTypeArguments().get(1)).getTypeArguments().get(0);
+  }
+
+  // TODO(cgruber): Consider an object that holds and exposes the various parts of a Map type.
+  /**
+   * returns the value type for a {@link Map} type like Map<K, V>}.
+   */
+  public static TypeMirror getValueTypeOfMap(DeclaredType mapType) {
+    checkState(MoreTypes.isTypeOf(Map.class, mapType), "%s is not a Map.", mapType);
+    return mapType.getTypeArguments().get(1);
+  }
+
+  /**
+   * Returns the key type for a {@link Map} type like Map<K, Provider<V>>}
+   */
+  public static TypeMirror getKeyTypeOfMap(DeclaredType mapType) {
+    checkState(MoreTypes.isTypeOf(Map.class, mapType), "%s is not a Map.", mapType);
+    return mapType.getTypeArguments().get(0);
+  }
+
+  /**
+   * Returns true if {@code type} is a {@link Map} whose value type is not a {@link Provider}.
+   */
+  public static boolean isMapWithNonProvidedValues(TypeMirror type) {
+    return MoreTypes.isType(type)
+        && MoreTypes.isTypeOf(Map.class, type)
+        && !MoreTypes.isTypeOf(Provider.class, asDeclared(type).getTypeArguments().get(1));
+  }
+
+  /**
+   * Returns true if {@code type} is a {@link Map} whose value type is a {@link Provider}.
+   */
+  public static boolean isMapWithProvidedValues(TypeMirror type) {
+    return MoreTypes.isType(type)
+        && MoreTypes.isTypeOf(Map.class, type)
+        && MoreTypes.isTypeOf(Provider.class, asDeclared(type).getTypeArguments().get(1));
+  }
+
+  /** Returns true if {@code type} is a {@code Set<Produced<T>>}. */
+  static boolean isSetOfProduced(TypeMirror type) {
+    return MoreTypes.isType(type)
+        && MoreTypes.isTypeOf(Set.class, type)
+        && MoreTypes.isTypeOf(Produced.class, MoreTypes.asDeclared(type).getTypeArguments().get(0));
+  }
+
+  /**
+   * Wraps an {@link Optional} of a type in an {@code Optional} of a {@link Wrapper} for that type.
+   */
+  static <T> Optional<Equivalence.Wrapper<T>> wrapOptionalInEquivalence(
+      Equivalence<T> equivalence, Optional<T> optional) {
+    return optional.isPresent()
+        ? Optional.of(equivalence.wrap(optional.get()))
+        : Optional.<Equivalence.Wrapper<T>>absent();
+  }
+
+  /**
+   * Unwraps an {@link Optional} of a {@link Wrapper} into an {@code Optional} of the underlying
+   * type.
+   */
+  static <T> Optional<T> unwrapOptionalEquivalence(
+      Optional<Equivalence.Wrapper<T>> wrappedOptional) {
+    return wrappedOptional.isPresent()
+        ? Optional.of(wrappedOptional.get().get())
+        : Optional.<T>absent();
+  }
+
+  private static boolean requiresEnclosingInstance(TypeElement typeElement) {
+    switch (typeElement.getNestingKind()) {
+      case TOP_LEVEL:
+        return false;
+      case MEMBER:
+        return !typeElement.getModifiers().contains(STATIC);
+      case ANONYMOUS:
+      case LOCAL:
+        return true;
+      default:
+        throw new AssertionError("TypeElement cannot have nesting kind: "
+            + typeElement.getNestingKind());
+    }
+  }
+
+  /**
+   * Returns true if and only if a component can instantiate new instances (typically of a module)
+   * rather than requiring that they be passed.
+   */
+  static boolean componentCanMakeNewInstances(TypeElement typeElement) {
+    switch (typeElement.getKind()) {
+      case CLASS:
+        break;
+      case ENUM:
+      case ANNOTATION_TYPE:
+      case INTERFACE:
+        return false;
+      default:
+        throw new AssertionError("TypeElement cannot have kind: " + typeElement.getKind());
+    }
+
+    if (typeElement.getModifiers().contains(ABSTRACT)) {
+      return false;
+    }
+
+    if (requiresEnclosingInstance(typeElement)) {
+      return false;
+    }
+
+    for (Element enclosed : typeElement.getEnclosedElements()) {
+      if (enclosed.getKind().equals(CONSTRUCTOR)
+          && ((ExecutableElement) enclosed).getParameters().isEmpty()
+          && !enclosed.getModifiers().contains(PRIVATE)) {
+        return true;
+      }
+    }
+
+    // TODO(gak): still need checks for visibility
+
+    return false;
+  }
+
+  static ImmutableSet<ExecutableElement> getUnimplementedMethods(
+      Elements elements, TypeElement type) {
+    ImmutableSet.Builder<ExecutableElement> unimplementedMethods = ImmutableSet.builder();
+    Set<ExecutableElement> methods = getLocalAndInheritedMethods(type, elements);
+    for (ExecutableElement method : methods) {
+      if (method.getModifiers().contains(Modifier.ABSTRACT)) {
+        unimplementedMethods.add(method);
+      }
+    }
+    return unimplementedMethods.build();
+  }
+
+  private Util() {}
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ValidationReport.java b/compiler/src/main/java/dagger/internal/codegen/ValidationReport.java
new file mode 100644
index 0000000..e174067
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ValidationReport.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.util.SimpleElementVisitor6;
+import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+
+import static javax.tools.Diagnostic.Kind.ERROR;
+import static javax.tools.Diagnostic.Kind.NOTE;
+import static javax.tools.Diagnostic.Kind.WARNING;
+
+/**
+ * A collection of items describing contractual issues with the code as presented to an annotation
+ * processor.  A "clean" report (i.e. with no issues) is a report with no {@linkplain Item items}
+ * and clean subreports. Callers will typically print the results of the report to a
+ * {@link Messager} instance using {@link #printMessagesTo}.
+ *
+ * <p>A report describes a subject {@link Element}.  Callers may choose to add report items about
+ * other elements that are contained within or related to the subject. Since {@link Diagnostic}
+ * reporting is expected to be associated with elements that are currently being compiled,
+ * {@link #printMessagesTo(Messager)} will only associate messages with non-subject elements if they
+ * are contained within the subject. Otherwise, they will be associated with the subject and contain
+ * a reference to the item's element in the message string. It is the responsibility of the caller
+ * to choose subjects that are part of the compilation.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@AutoValue
+abstract class ValidationReport<T extends Element> {
+  abstract T subject();
+  abstract ImmutableSet<Item> items();
+  abstract ImmutableSet<ValidationReport<?>> subreports();
+
+  boolean isClean() {
+    for (Item item : items()) {
+      switch (item.kind()) {
+        case ERROR:
+          return false;
+        default:
+          break;
+      }
+    }
+    for (ValidationReport<?> subreport : subreports()) {
+      if (!subreport.isClean()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  void printMessagesTo(Messager messager) {
+    for (Item item : items()) {
+      if (isEnclosedIn(subject(), item.element())) {
+        if (item.annotation().isPresent()) {
+          messager.printMessage(
+              item.kind(), item.message(), item.element(), item.annotation().get());
+        } else {
+          messager.printMessage(item.kind(), item.message(), item.element());
+        }
+      } else {
+        String message = String.format("[%s] %s", elementString(item.element()), item.message());
+        if (item.annotation().isPresent()) {
+          messager.printMessage(item.kind(), message, subject(), item.annotation().get());
+        } else {
+          messager.printMessage(item.kind(), message, subject());
+        }
+      }
+    }
+    for (ValidationReport<?> subreport : subreports()) {
+      subreport.printMessagesTo(messager);
+    }
+  }
+
+  private static String elementString(Element element) {
+    return element.accept(
+        new SimpleElementVisitor6<String, Void>() {
+          @Override
+          protected String defaultAction(Element e, Void p) {
+            return e.toString();
+          }
+
+          @Override
+          public String visitExecutable(ExecutableElement e, Void p) {
+            return e.getEnclosingElement().accept(this, null) + '.' + e.toString();
+          }
+        },
+        null);
+  }
+
+  private static boolean isEnclosedIn(Element parent, Element child) {
+    Element current = child;
+    while (current != null) {
+      if (current.equals(parent)) {
+        return true;
+      }
+      current = current.getEnclosingElement();
+    }
+    return false;
+  }
+
+  @AutoValue
+  static abstract class Item {
+    abstract String message();
+    abstract Kind kind();
+    abstract Element element();
+    abstract Optional<AnnotationMirror> annotation();
+  }
+
+  static <T extends Element> Builder<T> about(T subject) {
+    return new Builder<T>(subject);
+  }
+
+  static final class Builder<T extends Element> {
+    private final T subject;
+    private final ImmutableSet.Builder<Item> items = ImmutableSet.builder();
+    private final ImmutableSet.Builder<ValidationReport<?>> subreports = ImmutableSet.builder();
+
+    private Builder(T subject) {
+      this.subject = subject;
+    }
+
+    T getSubject() {
+      return subject;
+    }
+
+    Builder<T> addItems(Iterable<Item> newItems) {
+      items.addAll(newItems);
+      return this;
+    }
+
+    Builder<T> addError(String message) {
+      addItem(message, ERROR, subject, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addError(String message, Element element) {
+      addItem(message, ERROR, element, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addError(String message, Element element, AnnotationMirror annotation) {
+      addItem(message, ERROR, element, Optional.of(annotation));
+      return this;
+    }
+
+    Builder<T> addWarning(String message) {
+      addItem(message, WARNING, subject, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addWarning(String message, Element element) {
+      addItem(message, WARNING, element, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addWarning(String message, Element element, AnnotationMirror annotation) {
+      addItem(message, WARNING, element, Optional.of(annotation));
+      return this;
+    }
+
+    Builder<T> addNote(String message) {
+      addItem(message, NOTE, subject, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addNote(String message, Element element) {
+      addItem(message, NOTE, element, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addNote(String message, Element element, AnnotationMirror annotation) {
+      addItem(message, NOTE, element, Optional.of(annotation));
+      return this;
+    }
+
+    Builder<T> addItem(String message, Kind kind, Element element) {
+      addItem(message, kind, element, Optional.<AnnotationMirror>absent());
+      return this;
+    }
+
+    Builder<T> addItem(String message, Kind kind, Element element, AnnotationMirror annotation) {
+      addItem(message, kind, element, Optional.of(annotation));
+      return this;
+    }
+
+    private Builder<T> addItem(String message, Kind kind, Element element,
+        Optional<AnnotationMirror> annotation) {
+      items.add(new AutoValue_ValidationReport_Item(message, kind, element, annotation));
+      return this;
+    }
+
+    Builder<T> addSubreport(ValidationReport<?> subreport) {
+      subreports.add(subreport);
+      return this;
+    }
+
+    ValidationReport<T> build() {
+      return new AutoValue_ValidationReport<T>(subject, items.build(), subreports.build());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/ValidationType.java b/compiler/src/main/java/dagger/internal/codegen/ValidationType.java
new file mode 100644
index 0000000..d602072
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/ValidationType.java
@@ -0,0 +1,40 @@
+/*
+* Copyright (C) 2015 Google, Inc.
+*
+* 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 com.google.common.base.Optional;
+import javax.tools.Diagnostic;
+
+/**
+ * Allows options to control how component process validates things such as scope cycles
+ * or nullability.
+ */
+enum ValidationType {
+  ERROR,
+  WARNING,
+  NONE;
+
+  Optional<Diagnostic.Kind> diagnosticKind() {
+    switch (this) {
+      case ERROR:
+        return Optional.of(Diagnostic.Kind.ERROR);
+      case WARNING:
+        return Optional.of(Diagnostic.Kind.WARNING);
+      default:
+        return Optional.absent();
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/AnnotationWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/AnnotationWriter.java
new file mode 100644
index 0000000..8dbf27b
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/AnnotationWriter.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+
+import static dagger.internal.codegen.writer.Writables.toStringWritable;
+
+public final class AnnotationWriter implements Writable, HasClassReferences {
+  private final ClassName annotationName;
+  private final Set<HasClassReferences> memberReferences = Sets.newLinkedHashSet();
+  private final SortedMap<String, Writable> memberMap = Maps.newTreeMap();
+
+  AnnotationWriter(ClassName annotationName) {
+    this.annotationName = annotationName;
+  }
+
+  public void setValue(String value) {
+    setMember("value", value);
+  }
+
+  public void setMember(String name, int value) {
+    memberMap.put(name, toStringWritable(value));
+  }
+
+  public void setMember(String name, String value) {
+    memberMap.put(name, toStringWritable(StringLiteral.forValue(value)));
+  }
+
+  public <T extends Enum<T>> void setMember(String name, T value) {
+    Snippet snippet = Snippet.format("%s.%s", ClassName.fromClass(value.getClass()), value);
+    memberMap.put(name, snippet);
+    memberReferences.add(snippet);
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    appendable.append('@');
+    annotationName.write(appendable, context);
+    if (!memberMap.isEmpty()) {
+      appendable.append('(');
+      if (memberMap.size() == 1) {
+        Entry<String, Writable> onlyEntry = Iterables.getOnlyElement(memberMap.entrySet());
+        if (!onlyEntry.getKey().equals("value")) {
+          appendable.append(onlyEntry.getKey()).append(" = ");
+        }
+        onlyEntry.getValue().write(appendable, context);
+      }
+      appendable.append(')');
+    }
+    return appendable;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(memberReferences)
+        .append(annotationName)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/ArrayTypeName.java b/compiler/src/main/java/dagger/internal/codegen/writer/ArrayTypeName.java
new file mode 100644
index 0000000..e796062
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/ArrayTypeName.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import java.io.IOException;
+import java.util.Set;
+
+final class ArrayTypeName implements TypeName {
+  private final TypeName componentType;
+
+  ArrayTypeName(TypeName componentType) {
+    this.componentType = componentType;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return componentType.referencedClasses();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    return componentType.write(appendable, context).append("[]");
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return (obj instanceof ArrayTypeName)
+        && this.componentType.equals(((ArrayTypeName) obj).componentType);
+  }
+
+  @Override
+  public int hashCode() {
+    return componentType.hashCode();
+  }
+
+  @Override
+  public String toString() {
+    return Writables.writeToString(this);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/BlockWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/BlockWriter.java
new file mode 100644
index 0000000..c00dd5f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/BlockWriter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+public final class BlockWriter implements Writable, HasClassReferences {
+  private final List<Snippet> snippets;
+
+  BlockWriter() {
+    this.snippets = Lists.newArrayList();
+  }
+
+  public BlockWriter addSnippet(String snippet, Object... args) {
+    snippets.add(Snippet.format(snippet, args));
+    return this;
+  }
+
+  public BlockWriter addSnippet(Snippet snippet) {
+    snippets.add(snippet);
+    return this;
+  }
+
+  boolean isEmpty() {
+    return snippets.isEmpty();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    for (Snippet snippet : snippets) {
+      appendable.append('\n');
+      snippet.write(appendable, context);
+    }
+    return appendable.append('\n');
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(snippets)
+        .transformAndConcat(new Function<HasClassReferences, Set<ClassName>>() {
+          @Override
+          public Set<ClassName> apply(HasClassReferences input) {
+            return input.referencedClasses();
+          }
+        })
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/ClassName.java b/compiler/src/main/java/dagger/internal/codegen/writer/ClassName.java
new file mode 100644
index 0000000..bd0791f
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/ClassName.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Ascii;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.lang.model.element.NestingKind.MEMBER;
+import static javax.lang.model.element.NestingKind.TOP_LEVEL;
+
+/**
+ * Represents a fully-qualified class name for {@link NestingKind#TOP_LEVEL} and
+ * {@link NestingKind#MEMBER} classes.
+ *
+ * @since 2.0
+ */
+public final class ClassName implements TypeName, Comparable<ClassName> {
+  private String fullyQualifiedName = null;
+  private final String packageName;
+  /* From top to bottom.  E.g.: this field will contain ["A", "B"] for pgk.A.B.C */
+  private final ImmutableList<String> enclosingSimpleNames;
+  private final String simpleName;
+
+  private ClassName(String packageName, ImmutableList<String> enclosingSimpleNames,
+      String simpleName) {
+    this.packageName = packageName;
+    this.enclosingSimpleNames = enclosingSimpleNames;
+    this.simpleName = simpleName;
+  }
+
+  public String packageName() {
+    return packageName;
+  }
+
+  public ImmutableList<String> enclosingSimpleNames() {
+    return enclosingSimpleNames;
+  }
+
+  public Optional<ClassName> enclosingClassName() {
+    return enclosingSimpleNames.isEmpty()
+        ? Optional.<ClassName>absent()
+        : Optional.of(new ClassName(packageName,
+            enclosingSimpleNames.subList(0, enclosingSimpleNames.size() - 1),
+            enclosingSimpleNames.get(enclosingSimpleNames.size() - 1)));
+  }
+
+  public String simpleName() {
+    return simpleName;
+  }
+
+  public String canonicalName() {
+    if (fullyQualifiedName == null) {
+      StringBuilder builder = new StringBuilder(packageName());
+      if (builder.length() > 0) {
+        builder.append('.');
+      }
+      for (String enclosingSimpleName : enclosingSimpleNames()) {
+        builder.append(enclosingSimpleName).append('.');
+      }
+      fullyQualifiedName = builder.append(simpleName()).toString();
+    }
+    return fullyQualifiedName;
+  }
+
+  /**
+   * Equivalent to {@link #classFileName(char) classFileName('$')}
+   */
+  public String classFileName() {
+    return classFileName('$');
+  }
+
+  /**
+   * Returns the class name (excluding package).
+   *
+   * <p>The returned value includes the names of its enclosing classes (if any) but not the package
+   * name. e.g. {@code fromClass(Map.Entry.class).classFileName('_')} will return {@code Map_Entry}.
+   */
+  public String classFileName(char separator) {
+    StringBuilder builder = new StringBuilder();
+    for (String enclosingSimpleName : enclosingSimpleNames) {
+      builder.append(enclosingSimpleName).append(separator);
+    }
+    return builder.append(simpleName()).toString();
+  }
+
+  public ClassName topLevelClassName() {
+    Iterator<String> enclosingIterator = enclosingSimpleNames().iterator();
+    return enclosingIterator.hasNext()
+        ? new ClassName(packageName(), ImmutableList.<String>of(),
+            enclosingIterator.next())
+        : this;
+  }
+
+  public ClassName nestedClassNamed(String memberClassName) {
+    checkNotNull(memberClassName);
+    checkArgument(SourceVersion.isIdentifier(memberClassName));
+    return new ClassName(packageName(),
+        new ImmutableList.Builder<String>()
+            .addAll(enclosingSimpleNames())
+            .add(simpleName())
+            .build(),
+        memberClassName);
+  }
+
+  public ClassName peerNamed(String peerClassName) {
+    checkNotNull(peerClassName);
+    checkArgument(SourceVersion.isIdentifier(peerClassName));
+    return new ClassName(packageName(), enclosingSimpleNames(), peerClassName);
+  }
+
+  /**
+   * Returns a parameterized type name with this as its raw type if {@code parameters} is not empty.
+   * If {@code parameters} is empty, returns this object.
+   */
+  public TypeName withTypeParameters(List<? extends TypeName> parameters) {
+    return parameters.isEmpty() ? this : ParameterizedTypeName.create(this, parameters);
+  }
+
+  private static final ImmutableSet<NestingKind> ACCEPTABLE_NESTING_KINDS =
+      Sets.immutableEnumSet(TOP_LEVEL, MEMBER);
+
+  public static ClassName fromTypeElement(TypeElement element) {
+    checkNotNull(element);
+    checkArgument(ACCEPTABLE_NESTING_KINDS.contains(element.getNestingKind()));
+    String simpleName = element.getSimpleName().toString();
+    List<String> enclosingNames = new ArrayList<String>();
+    Element current = element.getEnclosingElement();
+    while (current.getKind().isClass() || current.getKind().isInterface()) {
+      checkArgument(ACCEPTABLE_NESTING_KINDS.contains(element.getNestingKind()));
+      enclosingNames.add(current.getSimpleName().toString());
+      current = current.getEnclosingElement();
+    }
+    PackageElement packageElement = getPackage(current);
+    Collections.reverse(enclosingNames);
+    return new ClassName(packageElement.getQualifiedName().toString(),
+        ImmutableList.copyOf(enclosingNames), simpleName);
+  }
+
+  public static ClassName fromClass(Class<?> clazz) {
+    checkNotNull(clazz);
+    List<String> enclosingNames = new ArrayList<String>();
+    Class<?> current = clazz.getEnclosingClass();
+    while (current != null) {
+      enclosingNames.add(current.getSimpleName());
+      current = current.getEnclosingClass();
+    }
+    Collections.reverse(enclosingNames);
+    return create(clazz.getPackage().getName(), enclosingNames, clazz.getSimpleName());
+  }
+
+  private static PackageElement getPackage(Element type) {
+    while (type.getKind() != ElementKind.PACKAGE) {
+      type = type.getEnclosingElement();
+    }
+    return (PackageElement) type;
+  }
+
+  /**
+   * Returns a new {@link ClassName} instance for the given fully-qualified class name string. This
+   * method assumes that the input is ASCII and follows typical Java style (lower-case package
+   * names, upper-camel-case class names) and may produce incorrect results or throw
+   * {@link IllegalArgumentException} otherwise. For that reason, {@link #fromClass(Class)} and
+   * {@link #fromClass(Class)} should be preferred as they can correctly create {@link ClassName}
+   * instances without such restrictions.
+   */
+  public static ClassName bestGuessFromString(String classNameString) {
+    checkNotNull(classNameString);
+    List<String> parts = Splitter.on('.').splitToList(classNameString);
+    int firstClassPartIndex = -1;
+    for (int i = 0; i < parts.size(); i++) {
+      String part = parts.get(i);
+      checkArgument(SourceVersion.isIdentifier(part));
+      char firstChar = part.charAt(0);
+      if (Ascii.isLowerCase(firstChar)) {
+        // looks like a package part
+        if (firstClassPartIndex >= 0) {
+          throw new IllegalArgumentException("couldn't make a guess for " + classNameString);
+        }
+      } else if (Ascii.isUpperCase(firstChar)) {
+        // looks like a class part
+        if (firstClassPartIndex < 0) {
+          firstClassPartIndex = i;
+        }
+      } else {
+        throw new IllegalArgumentException("couldn't make a guess for " + classNameString);
+      }
+    }
+    int lastIndex = parts.size() - 1;
+    return new ClassName(
+        Joiner.on('.').join(parts.subList(0, firstClassPartIndex)),
+        firstClassPartIndex == lastIndex
+            ? ImmutableList.<String>of()
+            : ImmutableList.copyOf(parts.subList(firstClassPartIndex, lastIndex)),
+        parts.get(lastIndex));
+  }
+
+  public static ClassName create(
+      String packageName, List<String> enclosingSimpleNames, String simpleName) {
+    return new ClassName(packageName, ImmutableList.copyOf(enclosingSimpleNames),
+        simpleName);
+  }
+
+  public static ClassName create(String packageName, String simpleName) {
+    return new ClassName(packageName, ImmutableList.<String>of(), simpleName);
+  }
+
+  @Override
+  public String toString() {
+    return canonicalName();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    appendable.append(context.sourceReferenceForClassName(this));
+    return appendable;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    } else if (obj instanceof ClassName) {
+      ClassName that = (ClassName) obj;
+      return this.packageName.equals(that.packageName)
+          && this.enclosingSimpleNames.equals(that.enclosingSimpleNames)
+          && this.simpleName.equals(that.simpleName);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(packageName, enclosingSimpleNames, simpleName);
+  }
+
+  @Override
+  public int compareTo(ClassName o) {
+    return canonicalName().compareTo(o.canonicalName());
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return ImmutableSet.of(this);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/ClassWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/ClassWriter.java
new file mode 100644
index 0000000..edaba3a
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/ClassWriter.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+
+import static com.google.common.base.Preconditions.checkState;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PROTECTED;
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+public final class ClassWriter extends TypeWriter {
+  private Optional<TypeName> superclass;
+  private final List<ConstructorWriter> constructorWriters;
+  private final List<TypeVariableName> typeParameters;
+
+  ClassWriter(ClassName className) {
+    super(className);
+    this.superclass = Optional.absent();
+    this.constructorWriters = Lists.newArrayList();
+    this.typeParameters = Lists.newArrayList();
+  }
+
+  public void setSuperclass(TypeName typeReference) {
+    checkState(!superclass.isPresent());
+    superclass = Optional.of(typeReference);
+  }
+
+  /**
+   * If {@code supertype} is a class, makes this class extend it; if it is an interface, makes this
+   * class implement it.
+   */
+  public void setSupertype(TypeElement supertype) {
+    switch (supertype.getKind()) {
+      case CLASS:
+        setSuperclass(ClassName.fromTypeElement(supertype));
+        break;
+      case INTERFACE:
+        addImplementedType(supertype);
+        break;
+      default:
+        throw new IllegalArgumentException(supertype + " must be a class or interface");
+    }
+  }
+
+  public ConstructorWriter addConstructor() {
+    ConstructorWriter constructorWriter = new ConstructorWriter(name.simpleName());
+    constructorWriters.add(constructorWriter);
+    return constructorWriter;
+  }
+
+  public void addTypeParameter(TypeVariableName typeVariableName) {
+    this.typeParameters.add(typeVariableName);
+  }
+
+  public void addTypeParameters(Iterable<TypeVariableName> typeVariableNames) {
+    Iterables.addAll(typeParameters, typeVariableNames);
+  }
+
+  public List<TypeVariableName> typeParameters() {
+    return ImmutableList.copyOf(typeParameters);
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    context = context.createSubcontext(FluentIterable.from(nestedTypeWriters)
+        .transform(new Function<TypeWriter, ClassName>() {
+          @Override public ClassName apply(TypeWriter input) {
+            return input.name;
+          }
+        })
+        .toSet());
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable).append("class ").append(name.simpleName());
+    Writables.join(", ", typeParameters, "<", ">", appendable, context);
+    if (superclass.isPresent()) {
+      appendable.append(" extends ");
+      superclass.get().write(appendable, context);
+    }
+    Writables.join(", ", implementedTypes, " implements ", "", appendable, context);
+    appendable.append(" {");
+    if (!fieldWriters.isEmpty()) {
+      appendable.append('\n');
+    }
+    for (VariableWriter fieldWriter : fieldWriters.values()) {
+      fieldWriter.write(new IndentingAppendable(appendable), context).append("\n");
+    }
+    for (ConstructorWriter constructorWriter : constructorWriters) {
+      appendable.append('\n');
+      if (!isDefaultConstructor(constructorWriter)) {
+        constructorWriter.write(new IndentingAppendable(appendable), context);
+      }
+    }
+    for (MethodWriter methodWriter : methodWriters) {
+      appendable.append('\n');
+      methodWriter.write(new IndentingAppendable(appendable), context);
+    }
+    for (TypeWriter nestedTypeWriter : nestedTypeWriters) {
+      appendable.append('\n');
+      nestedTypeWriter.write(new IndentingAppendable(appendable), context);
+    }
+    appendable.append("}\n");
+    return appendable;
+  }
+
+  private static final Set<Modifier> VISIBILIY_MODIFIERS =
+      Sets.immutableEnumSet(PUBLIC, PROTECTED, PRIVATE);
+
+  private boolean isDefaultConstructor(ConstructorWriter constructorWriter) {
+    return Sets.intersection(VISIBILIY_MODIFIERS, modifiers)
+        .equals(Sets.intersection(VISIBILIY_MODIFIERS, constructorWriter.modifiers))
+        && constructorWriter.body().isEmpty();
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(nestedTypeWriters)
+        .append(fieldWriters.values())
+        .append(constructorWriters)
+        .append(methodWriters)
+        .append(implementedTypes)
+        .append(superclass.asSet())
+        .append(annotations)
+        .append(typeParameters)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/ConstructorWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/ConstructorWriter.java
new file mode 100644
index 0000000..387c1dd
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/ConstructorWriter.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.TypeElement;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public final class ConstructorWriter extends Modifiable implements Writable, HasClassReferences {
+  private final String name;
+  private final Map<String, VariableWriter> parameterWriters;
+  private final BlockWriter blockWriter;
+
+  ConstructorWriter(String name) {
+    this.name = name;
+    this.parameterWriters = Maps.newLinkedHashMap();
+    this.blockWriter = new BlockWriter();
+  }
+
+  public VariableWriter addParameter(Class<?> type, String name) {
+    return addParameter(ClassName.fromClass(type), name);
+  }
+
+  public VariableWriter addParameter(TypeElement type, String name) {
+    return addParameter(ClassName.fromTypeElement(type), name);
+  }
+
+  public VariableWriter addParameter(TypeWriter type, String name) {
+    return addParameter(type.name, name);
+  }
+
+  public VariableWriter addParameter(TypeName type, String name) {
+    VariableWriter parameterWriter = new VariableWriter(type, name);
+    parameterWriters.put(name, parameterWriter);
+    return parameterWriter;
+  }
+  
+  public Map<String, TypeName> parameters() {
+    ImmutableMap.Builder<String, TypeName> params = ImmutableMap.builder();
+    for (Map.Entry<String, VariableWriter> entry : parameterWriters.entrySet()) {
+      params.put(entry.getKey(), entry.getValue().type());
+    }
+    return params.build();
+  }
+
+  public BlockWriter body() {
+    return blockWriter;
+  }
+
+  private VariableWriter addParameter(ClassName type, String name) {
+    checkArgument(!parameterWriters.containsKey(name));
+    VariableWriter parameterWriter = new VariableWriter(type, name);
+    parameterWriters.put(name, parameterWriter);
+    return parameterWriter;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(parameterWriters.values())
+        .append(annotations)
+        .append(blockWriter)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable).append(name).append('(');
+    Writables.join(", ", parameterWriters.values(), appendable, context);
+    appendable.append(") {");
+    blockWriter.write(new IndentingAppendable(appendable), context);
+    return appendable.append("}\n");
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/EnumWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/EnumWriter.java
new file mode 100644
index 0000000..4ab017d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/EnumWriter.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.Modifier;
+
+import static com.google.common.base.Preconditions.checkState;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PROTECTED;
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+public final class EnumWriter extends TypeWriter {
+  private final Map<String, ConstantWriter> constantWriters = Maps.newLinkedHashMap();
+  private final List<ConstructorWriter> constructorWriters = Lists.newArrayList();
+
+  EnumWriter(ClassName name) {
+    super(name);
+  }
+
+  public ConstantWriter addConstant(String name) {
+    ConstantWriter constantWriter = new ConstantWriter(name);
+    constantWriters.put(name, constantWriter);
+    return constantWriter;
+  }
+
+  public ConstructorWriter addConstructor() {
+    ConstructorWriter constructorWriter = new ConstructorWriter(name.simpleName());
+    constructorWriters.add(constructorWriter);
+    return constructorWriter;
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    context = context.createSubcontext(FluentIterable.from(nestedTypeWriters)
+        .transform(new Function<TypeWriter, ClassName>() {
+          @Override public ClassName apply(TypeWriter input) {
+            return input.name;
+          }
+        })
+        .toSet());
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable).append("enum ").append(name.simpleName());
+    Iterator<TypeName> implementedTypesIterator = implementedTypes.iterator();
+    if (implementedTypesIterator.hasNext()) {
+      appendable.append(" implements ");
+      implementedTypesIterator.next().write(appendable, context);
+      while (implementedTypesIterator.hasNext()) {
+        appendable.append(", ");
+        implementedTypesIterator.next().write(appendable, context);
+      }
+    }
+    appendable.append(" {");
+
+    checkState(!constantWriters.isEmpty(), "Cannot write an enum with no constants.");
+    appendable.append('\n');
+    ImmutableList<ConstantWriter> constantWriterList =
+        ImmutableList.copyOf(constantWriters.values());
+    for (ConstantWriter constantWriter
+        : constantWriterList.subList(0, constantWriterList.size() - 1)) {
+      constantWriter.write(appendable, context);
+      appendable.append(",\n");
+    }
+    constantWriterList.get(constantWriterList.size() - 1).write(appendable, context);
+    appendable.append(";\n");
+
+    if (!fieldWriters.isEmpty()) {
+      appendable.append('\n');
+    }
+    for (VariableWriter fieldWriter : fieldWriters.values()) {
+      fieldWriter.write(new IndentingAppendable(appendable), context).append("\n");
+    }
+    for (ConstructorWriter constructorWriter : constructorWriters) {
+      appendable.append('\n');
+      if (!isDefaultConstructor(constructorWriter)) {
+        constructorWriter.write(new IndentingAppendable(appendable), context);
+      }
+    }
+    for (MethodWriter methodWriter : methodWriters) {
+      appendable.append('\n');
+      methodWriter.write(new IndentingAppendable(appendable), context);
+    }
+    for (TypeWriter nestedTypeWriter : nestedTypeWriters) {
+      appendable.append('\n');
+      nestedTypeWriter.write(new IndentingAppendable(appendable), context);
+    }
+    appendable.append("}\n");
+    return appendable;
+  }
+
+  private static final Set<Modifier> VISIBILIY_MODIFIERS =
+      Sets.immutableEnumSet(PUBLIC, PROTECTED, PRIVATE);
+
+  private boolean isDefaultConstructor(ConstructorWriter constructorWriter) {
+    return Sets.intersection(VISIBILIY_MODIFIERS, modifiers)
+        .equals(Sets.intersection(VISIBILIY_MODIFIERS, constructorWriter.modifiers))
+        && constructorWriter.body().isEmpty();
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(nestedTypeWriters)
+        .append(constantWriters.values())
+        .append(fieldWriters.values())
+        .append(constructorWriters)
+        .append(methodWriters)
+        .append(implementedTypes)
+        .append(annotations)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+
+  public static final class ConstantWriter implements Writable, HasClassReferences {
+    private final String name;
+    private final List<Snippet> constructorSnippets;
+
+    private ConstantWriter(String name) {
+      this.name = name;
+      this.constructorSnippets = Lists.newArrayList();
+    }
+
+    ConstantWriter addArgument(Snippet snippet) {
+      constructorSnippets.add(snippet);
+      return this;
+    }
+
+    @Override
+    public Appendable write(Appendable appendable, Context context) throws IOException {
+      appendable.append(name);
+      Iterator<Snippet> snippetIterator = constructorSnippets.iterator();
+      if (snippetIterator.hasNext()) {
+        appendable.append('(');
+        snippetIterator.next().write(appendable, context);
+        while (snippetIterator.hasNext()) {
+          appendable.append(", ");
+          snippetIterator.next().write(appendable, context);
+        }
+        appendable.append(')');
+      }
+      return appendable;
+    }
+
+    @Override
+    public Set<ClassName> referencedClasses() {
+      return FluentIterable.from(constructorSnippets)
+          .transformAndConcat(HasClassReferences.COMBINER)
+          .toSet();
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/FieldWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/FieldWriter.java
new file mode 100644
index 0000000..b45e5d9
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/FieldWriter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.io.IOException;
+import java.util.Set;
+
+public final class FieldWriter extends VariableWriter {
+  private Optional<Snippet> initializer;
+
+  FieldWriter(TypeName type, String name) {
+    super(type, name);
+    this.initializer = Optional.absent();
+  }
+
+  public void setInitializer(Snippet initializer) {
+    this.initializer = Optional.of(initializer);
+  }
+
+  public void setInitializer(String initializer, Object... args) {
+    this.initializer = Optional.of(Snippet.format(initializer, args));
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    super.write(appendable, context);
+    if (initializer.isPresent()) {
+      appendable.append(" = ");
+      initializer.get().write(appendable, context);
+    }
+    appendable.append(';');
+    return appendable;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    Iterable<? extends HasClassReferences> concat =
+        Iterables.concat(ImmutableList.of(type()), initializer.asSet(), annotations);
+    return FluentIterable.from(concat)
+        .transformAndConcat(new Function<HasClassReferences, Set<ClassName>>() {
+          @Override
+          public Set<ClassName> apply(HasClassReferences input) {
+            return input.referencedClasses();
+          }
+        })
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/HasClassReferences.java b/compiler/src/main/java/dagger/internal/codegen/writer/HasClassReferences.java
new file mode 100644
index 0000000..e463ea2
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/HasClassReferences.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import java.util.Set;
+
+public interface HasClassReferences {
+  Set<ClassName> referencedClasses();
+
+  static final Function<HasClassReferences, Set<ClassName>> COMBINER =
+      new Function<HasClassReferences, Set<ClassName>>() {
+        @Override
+        public Set<ClassName> apply(HasClassReferences input) {
+          return input.referencedClasses();
+        }
+      };
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/HasTypeName.java b/compiler/src/main/java/dagger/internal/codegen/writer/HasTypeName.java
new file mode 100644
index 0000000..a6909ed
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/HasTypeName.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+interface HasTypeName {
+  TypeName name();
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/IndentingAppendable.java b/compiler/src/main/java/dagger/internal/codegen/writer/IndentingAppendable.java
new file mode 100644
index 0000000..d96f8a3
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/IndentingAppendable.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.AbstractIterator;
+import java.io.IOException;
+import java.util.Iterator;
+
+final class IndentingAppendable implements Appendable {
+  private final String indentation;
+  private final Appendable delegate;
+  private boolean requiresIndent = true;
+
+  IndentingAppendable(Appendable delegate) {
+    this("  ", delegate);
+  }
+
+  IndentingAppendable(String indentation, Appendable delegate) {
+    this.indentation = indentation;
+    this.delegate = delegate;
+  }
+
+  @Override
+  public Appendable append(CharSequence csq) throws IOException {
+    return append(csq, 0, csq.length());
+  }
+
+  @Override
+  public Appendable append(CharSequence csq, int start, int end) throws IOException {
+    Iterator<CharSequence> lines = lines(csq, start, end);
+    while (lines.hasNext()) {
+      CharSequence line = lines.next();
+      maybeIndent();
+      delegate.append(line);
+      if (line.charAt(line.length() - 1) == '\n') {
+        requiresIndent = true;
+      }
+    }
+    return this;
+  }
+
+  @Override
+  public Appendable append(char c) throws IOException {
+    maybeIndent();
+    delegate.append(c);
+    if (c == '\n') {
+      requiresIndent = true;
+    }
+    return this;
+  }
+
+  void maybeIndent() throws IOException {
+    if (requiresIndent) {
+      delegate.append(indentation);
+    }
+    requiresIndent = false;
+  }
+
+  private static Iterator<CharSequence> lines(
+      final CharSequence csq, final int start, final int end) {
+    return new AbstractIterator<CharSequence>() {
+      int index = start;
+
+      @Override protected CharSequence computeNext() {
+        int nextStart = index;
+        while (index < end && csq.charAt(index) != '\n') {
+          index++;
+        }
+        if (index < end && csq.charAt(index) == '\n') {
+          index++;
+        }
+        int nextEnd = index;
+        return nextStart >= end
+            ? endOfData()
+            : csq.subSequence(nextStart, nextEnd);
+      }
+    };
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/InterfaceWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/InterfaceWriter.java
new file mode 100644
index 0000000..ffcfc75
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/InterfaceWriter.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public final class InterfaceWriter extends TypeWriter {
+  private final List<TypeVariableName> typeVariables;
+  InterfaceWriter(ClassName name) {
+    super(name);
+    this.typeVariables = Lists.newArrayList();
+  }
+
+  public void addTypeVariable(TypeVariableName typeVariable) {
+    this.typeVariables.add(typeVariable);
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    context = context.createSubcontext(FluentIterable.from(nestedTypeWriters)
+        .transform(new Function<TypeWriter, ClassName>() {
+          @Override public ClassName apply(TypeWriter input) {
+            return input.name;
+          }
+        })
+        .toSet());
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable).append("interface ").append(name.simpleName());
+    if (!typeVariables.isEmpty()) {
+      appendable.append('<');
+      Joiner.on(", ").appendTo(appendable, typeVariables);
+      appendable.append('>');
+    }
+    Iterator<TypeName> implementedTypesIterator = implementedTypes.iterator();
+    if (implementedTypesIterator.hasNext()) {
+      appendable.append(" extends ");
+      implementedTypesIterator.next().write(appendable, context);
+      while (implementedTypesIterator.hasNext()) {
+        appendable.append(", ");
+        implementedTypesIterator.next().write(appendable, context);
+      }
+    }
+    appendable.append(" {");
+    for (MethodWriter methodWriter : methodWriters) {
+      appendable.append('\n');
+      methodWriter.write(new IndentingAppendable(appendable), context);
+    }
+    for (TypeWriter nestedTypeWriter : nestedTypeWriters) {
+      appendable.append('\n');
+      nestedTypeWriter.write(new IndentingAppendable(appendable), context);
+    }
+    appendable.append("}\n");
+    return appendable;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(nestedTypeWriters)
+        .append(methodWriters)
+        .append(implementedTypes)
+        .append(annotations)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/JavaWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/JavaWriter.java
new file mode 100644
index 0000000..5977371
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/JavaWriter.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import com.google.common.io.CharSink;
+import com.google.common.io.CharSource;
+import com.google.googlejavaformat.java.Formatter;
+import com.google.googlejavaformat.java.FormatterException;
+import dagger.internal.codegen.writer.Writable.Context;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.tools.JavaFileObject;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.unmodifiableList;
+
+/**
+ * Writes a single compilation unit.
+ */
+public final class JavaWriter {
+  public static JavaWriter inPackage(String packageName) {
+    return new JavaWriter(packageName);
+  }
+
+  public static JavaWriter inPackage(Package enclosingPackage) {
+    return new JavaWriter(enclosingPackage.getName());
+  }
+
+  public static JavaWriter inPackage(PackageElement packageElement) {
+    return new JavaWriter(packageElement.getQualifiedName().toString());
+  }
+
+  private final String packageName;
+  // TODO(gak): disallow multiple types in a file?
+  private final List<TypeWriter> typeWriters;
+  private final List<ClassName> explicitImports;
+
+  private JavaWriter(String packageName) {
+    this.packageName = packageName;
+    this.typeWriters = Lists.newArrayList();
+    this.explicitImports = Lists.newArrayList();
+  }
+
+  public List<TypeWriter> getTypeWriters() {
+    return unmodifiableList(typeWriters);
+  }
+
+  public JavaWriter addImport(Class<?> importedClass) {
+    explicitImports.add(ClassName.fromClass(importedClass));
+    return this;
+  }
+
+  public ClassWriter addClass(String simpleName) {
+    checkNotNull(simpleName);
+    ClassWriter classWriter = new ClassWriter(ClassName.create(packageName, simpleName));
+    typeWriters.add(classWriter);
+    return classWriter;
+  }
+
+  public EnumWriter addEnum(String simpleName) {
+    checkNotNull(simpleName);
+    EnumWriter writer = new EnumWriter(ClassName.create(packageName, simpleName));
+    typeWriters.add(writer);
+    return writer;
+  }
+
+  public InterfaceWriter addInterface(String simpleName) {
+    InterfaceWriter writer = new InterfaceWriter(ClassName.create(packageName, simpleName));
+    typeWriters.add(writer);
+    return writer;
+  }
+
+  public <A extends Appendable> A write(A appendable) throws IOException {
+    if (!packageName.isEmpty()) {
+      appendable.append("package ").append(packageName).append(";\n\n");
+    }
+
+    // write imports
+    ImmutableSet<ClassName> classNames = FluentIterable.from(typeWriters)
+        .transformAndConcat(new Function<HasClassReferences, Set<ClassName>>() {
+          @Override
+          public Set<ClassName> apply(HasClassReferences input) {
+            return input.referencedClasses();
+          }
+        })
+        .toSet();
+
+    ImmutableSortedSet<ClassName> importCandidates = ImmutableSortedSet.<ClassName>naturalOrder()
+        .addAll(explicitImports)
+        .addAll(classNames)
+        .build();
+    ImmutableSet<ClassName> typeNames = FluentIterable.from(typeWriters)
+        .transform(new Function<TypeWriter, ClassName>() {
+          @Override public ClassName apply(TypeWriter input) {
+            return input.name;
+          }
+        })
+        .toSet();
+
+    ImmutableSet.Builder<String> declaredSimpleNamesBuilder = ImmutableSet.builder();
+    Deque<TypeWriter> declaredTypes = new ArrayDeque<>(typeWriters);
+    while (!declaredTypes.isEmpty()) {
+      TypeWriter currentType = declaredTypes.pop();
+      declaredSimpleNamesBuilder.add(currentType.name().simpleName());
+      declaredTypes.addAll(currentType.nestedTypeWriters);
+    }
+
+    ImmutableSet<String> declaredSimpleNames = declaredSimpleNamesBuilder.build();
+
+    BiMap<String, ClassName> importedClassIndex = HashBiMap.create();
+    for (ClassName className : importCandidates) {
+      if (!(className.packageName().equals(packageName)
+              && !className.enclosingClassName().isPresent())
+          && !(className.packageName().equals("java.lang")
+              && className.enclosingSimpleNames().isEmpty())
+          && !typeNames.contains(className.topLevelClassName())) {
+        Optional<ClassName> importCandidate = Optional.of(className);
+        while (importCandidate.isPresent()
+            && (importedClassIndex.containsKey(importCandidate.get().simpleName())
+                || declaredSimpleNames.contains(importCandidate.get().simpleName()))) {
+          importCandidate = importCandidate.get().enclosingClassName();
+        }
+        if (importCandidate.isPresent()) {
+          appendable.append("import ").append(importCandidate.get().canonicalName()).append(";\n");
+          importedClassIndex.put(importCandidate.get().simpleName(), importCandidate.get());
+        }
+      }
+    }
+
+    appendable.append('\n');
+
+    CompilationUnitContext context =
+        new CompilationUnitContext(packageName, ImmutableSet.copyOf(importedClassIndex.values()));
+
+    // write types
+    for (TypeWriter typeWriter : typeWriters) {
+      typeWriter.write(appendable, context.createSubcontext(typeNames)).append('\n');
+    }
+    return appendable;
+  }
+
+  public void file(Filer filer, Iterable<? extends Element> originatingElements)
+      throws IOException {
+    file(filer, Iterables.getOnlyElement(typeWriters).name.canonicalName(), originatingElements);
+  }
+
+  public void file(Filer filer, CharSequence name,  Iterable<? extends Element> originatingElements)
+      throws IOException {
+    final JavaFileObject sourceFile = filer.createSourceFile(name,
+        Iterables.toArray(originatingElements, Element.class));
+    try {
+      new Formatter().formatSource(
+          CharSource.wrap(write(new StringBuilder())),
+          new CharSink() {
+            @Override public Writer openStream() throws IOException {
+              return sourceFile.openWriter();
+            }
+          });
+    } catch (FormatterException e) {
+      throw new IllegalStateException(
+          "The writer produced code that could not be parsed by the formatter", e);
+    }
+  }
+
+  @Override
+  public String toString() {
+    try {
+      return write(new StringBuilder()).toString();
+    } catch (IOException e) {
+      throw new AssertionError();
+    }
+  }
+
+  static final class CompilationUnitContext implements Context {
+    private final String packageName;
+    private final ImmutableSortedSet<ClassName> visibleClasses;
+
+    CompilationUnitContext(String packageName, Set<ClassName> visibleClasses) {
+      this.packageName = packageName;
+      this.visibleClasses =
+          ImmutableSortedSet.copyOf(Ordering.natural().reverse(), visibleClasses);
+    }
+
+    @Override
+    public Context createSubcontext(Set<ClassName> newTypes) {
+      return new CompilationUnitContext(packageName, Sets.union(visibleClasses, newTypes));
+    }
+
+    @Override
+    public String sourceReferenceForClassName(ClassName className) {
+      if (isImported(className)) {
+        return className.simpleName();
+      }
+      Optional<ClassName> enclosingClassName = className.enclosingClassName();
+      while (enclosingClassName.isPresent()) {
+        if (isImported(enclosingClassName.get())) {
+          return enclosingClassName.get().simpleName()
+              + className.canonicalName()
+                  .substring(enclosingClassName.get().canonicalName().length());
+        }
+        enclosingClassName = enclosingClassName.get().enclosingClassName();
+      }
+      return className.canonicalName();
+    }
+
+    private boolean collidesWithVisibleClass(ClassName className) {
+      return collidesWithVisibleClass(className.simpleName());
+    }
+
+    private boolean collidesWithVisibleClass(String simpleName) {
+      return FluentIterable.from(visibleClasses)
+          .transform(new Function<ClassName, String>() {
+            @Override public String apply(ClassName input) {
+              return input.simpleName();
+            }
+          })
+          .contains(simpleName);
+    }
+
+    private boolean isImported(ClassName className) {
+      return (packageName.equals(className.packageName())
+              && !className.enclosingClassName().isPresent()
+              && !collidesWithVisibleClass(className)) // need to account for scope & hiding
+          || visibleClasses.contains(className)
+          || (className.packageName().equals("java.lang")
+              && className.enclosingSimpleNames().isEmpty());
+    }
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/MethodWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/MethodWriter.java
new file mode 100644
index 0000000..eb4ff8d
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/MethodWriter.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.TypeElement;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public final class MethodWriter extends Modifiable implements HasClassReferences, Writable {
+  private final TypeName returnType;
+  private final String name;
+  private final Map<String, VariableWriter> parameterWriters;
+  private final List<TypeVariableName> typeParameters;
+  private Optional<BlockWriter> body;
+
+  MethodWriter(TypeName returnType, String name) {
+    this.returnType = returnType;
+    this.name = name;
+    this.parameterWriters = Maps.newLinkedHashMap();
+    this.typeParameters = Lists.newArrayList();
+    this.body = Optional.absent();
+  }
+
+  public String name() {
+    return name;
+  }
+  
+  public TypeName returnType() {
+    return returnType;
+  }
+  
+  public void addTypeParameter(TypeVariableName typeVariableName) {
+    this.typeParameters.add(typeVariableName);
+  }
+  
+  public void addTypeParameters(Iterable<TypeVariableName> typeVariableNames) {
+    Iterables.addAll(typeParameters, typeVariableNames);
+  }
+
+  public VariableWriter addParameter(Class<?> type, String name) {
+    return addParameter(ClassName.fromClass(type), name);
+  }
+
+  public VariableWriter addParameter(TypeElement type, String name) {
+    return addParameter(ClassName.fromTypeElement(type), name);
+  }
+
+  public VariableWriter addParameter(TypeWriter type, String name) {
+    return addParameter(type.name, name);
+  }
+
+  public VariableWriter addParameter(TypeName type, String name) {
+    checkArgument(!parameterWriters.containsKey(name));
+    VariableWriter parameterWriter = new VariableWriter(type, name);
+    parameterWriters.put(name, parameterWriter);
+    return parameterWriter;
+  }
+
+  public BlockWriter body() {
+    if (body.isPresent()) {
+      return body.get();
+    } else {
+      BlockWriter blockWriter = new BlockWriter();
+      body = Optional.of(blockWriter);
+      return blockWriter;
+    }
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable);
+    Writables.join(", ", typeParameters, "<", "> ", appendable, context);
+    returnType.write(appendable, context);
+    appendable.append(' ').append(name).append('(');
+    Writables.join(", ", parameterWriters.values(), appendable, context);
+    appendable.append(")");
+    if (body.isPresent()) {
+      appendable.append(" {");
+      body.get().write(new IndentingAppendable(appendable), context);
+      appendable.append("}\n");
+    } else {
+      appendable.append(";\n");
+    }
+    return appendable;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(parameterWriters.values())
+        .append(returnType)
+        .append(body.asSet())
+        .append(annotations)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/Modifiable.java b/compiler/src/main/java/dagger/internal/codegen/writer/Modifiable.java
new file mode 100644
index 0000000..bb4c6ff
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/Modifiable.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import dagger.internal.codegen.writer.Writable.Context;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Modifier;
+
+public abstract class Modifiable {
+  final Set<Modifier> modifiers;
+  final List<AnnotationWriter> annotations;
+
+  Modifiable() {
+    this.modifiers = EnumSet.noneOf(Modifier.class);
+    this.annotations = Lists.newArrayList();
+  }
+
+  public void addModifiers(Modifier first, Modifier... rest) {
+    addModifiers(Lists.asList(first, rest));
+  }
+
+  public void addModifiers(Iterable<Modifier> modifiers) {
+    Iterables.addAll(this.modifiers, modifiers);
+  }
+
+  public AnnotationWriter annotate(ClassName annotation) {
+    AnnotationWriter annotationWriter = new AnnotationWriter(annotation);
+    this.annotations.add(annotationWriter);
+    return annotationWriter;
+  }
+
+  public AnnotationWriter annotate(Class<? extends Annotation> annotation) {
+    return annotate(ClassName.fromClass(annotation));
+  }
+
+  Appendable writeModifiers(Appendable appendable) throws IOException {
+    for (Modifier modifier : modifiers) {
+      appendable.append(modifier.toString()).append(' ');
+    }
+    return appendable;
+  }
+
+  Appendable writeAnnotations(Appendable appendable, Context context) throws IOException {
+    for (AnnotationWriter annotationWriter : annotations) {
+      annotationWriter.write(appendable, context).append('\n');
+    }
+    return appendable;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/NullName.java b/compiler/src/main/java/dagger/internal/codegen/writer/NullName.java
new file mode 100644
index 0000000..0d3588b
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/NullName.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Set;
+
+enum NullName implements TypeName {
+  NULL;
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return ImmutableSet.of();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    return appendable.append("null");
+  }
+
+  @Override
+  public String toString() {
+    return "null";
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/ParameterizedTypeName.java b/compiler/src/main/java/dagger/internal/codegen/writer/ParameterizedTypeName.java
new file mode 100644
index 0000000..e46a961
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/ParameterizedTypeName.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verify;
+
+public final class ParameterizedTypeName implements TypeName {
+  private final ClassName type;
+  private final ImmutableList<TypeName> parameters;
+
+  ParameterizedTypeName(ClassName type, Iterable<? extends TypeName> parameters) {
+    this.type = type;
+    this.parameters = ImmutableList.<TypeName>copyOf(parameters);
+  }
+  
+  public ClassName type() {
+    return type;
+  }
+  
+  public ImmutableList<TypeName> parameters() {
+    return parameters;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    ImmutableSet.Builder<ClassName> builder = new ImmutableSet.Builder<ClassName>()
+        .add(type);
+    for (TypeName parameter : parameters) {
+      builder.addAll(parameter.referencedClasses());
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    appendable.append(context.sourceReferenceForClassName(type));
+    Iterator<? extends TypeName> parameterIterator = parameters.iterator();
+    verify(parameterIterator.hasNext(), type.toString());
+    appendable.append('<');
+    parameterIterator.next().write(appendable, context);
+    while (parameterIterator.hasNext()) {
+      appendable.append(", ");
+      parameterIterator.next().write(appendable, context);
+    }
+    appendable.append('>');
+    return appendable;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof ParameterizedTypeName) {
+      ParameterizedTypeName that = (ParameterizedTypeName) obj;
+      return this.type.equals(that.type)
+          && this.parameters.equals(that.parameters);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(type, parameters);
+  }
+
+  @Override
+  public String toString() {
+    return Writables.writeToString(this);
+  }
+
+  public static ParameterizedTypeName create(ClassName className,
+      TypeName... parameters) {
+    return new ParameterizedTypeName(className, ImmutableList.copyOf(parameters));
+  }
+
+  public static ParameterizedTypeName create(ClassName className,
+      Iterable<? extends TypeName> parameters) {
+    return new ParameterizedTypeName(className, ImmutableList.copyOf(parameters));
+  }
+
+  public static ParameterizedTypeName create(Class<?> parameterizedClass,
+      TypeName... parameters) {
+    checkArgument(parameterizedClass.getTypeParameters().length == parameters.length);
+    return new ParameterizedTypeName(ClassName.fromClass(parameterizedClass),
+        ImmutableList.copyOf(parameters));
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/PrimitiveName.java b/compiler/src/main/java/dagger/internal/codegen/writer/PrimitiveName.java
new file mode 100644
index 0000000..94961dd
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/PrimitiveName.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Ascii;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Set;
+import javax.lang.model.type.PrimitiveType;
+
+public enum PrimitiveName implements TypeName {
+  BOOLEAN, BYTE, SHORT, INT, LONG, CHAR, FLOAT, DOUBLE;
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return ImmutableSet.of();
+  }
+
+  @Override
+  public String toString() {
+    return Ascii.toLowerCase(name());
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    return appendable.append(toString());
+  }
+
+  static PrimitiveName forTypeMirror(PrimitiveType mirror) {
+    switch (mirror.getKind()) {
+      case BOOLEAN:
+        return BOOLEAN;
+      case BYTE:
+        return BYTE;
+      case SHORT:
+        return SHORT;
+      case INT:
+        return INT;
+      case LONG:
+        return LONG;
+      case CHAR:
+        return CHAR;
+      case FLOAT:
+        return FLOAT;
+      case DOUBLE:
+        return DOUBLE;
+      default:
+        throw new AssertionError();
+    }
+  }
+
+  static PrimitiveName forClass(Class<?> primitiveClass) {
+    if (boolean.class.equals(primitiveClass)) {
+      return BOOLEAN;
+    }
+    if (byte.class.equals(primitiveClass)) {
+      return BYTE;
+    }
+    if (short.class.equals(primitiveClass)) {
+      return SHORT;
+    }
+    if (int.class.equals(primitiveClass)) {
+      return INT;
+    }
+    if (long.class.equals(primitiveClass)) {
+      return LONG;
+    }
+    if (char.class.equals(primitiveClass)) {
+      return CHAR;
+    }
+    if (float.class.equals(primitiveClass)) {
+      return FLOAT;
+    }
+    if (double.class.equals(primitiveClass)) {
+      return DOUBLE;
+    }
+    throw new IllegalArgumentException(primitiveClass + " is not a primitive type");
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/Snippet.java b/compiler/src/main/java/dagger/internal/codegen/writer/Snippet.java
new file mode 100644
index 0000000..80ab944
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/Snippet.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.Iterator;
+import java.util.Set;
+
+public abstract class Snippet implements HasClassReferences, Writable {
+
+  abstract ImmutableSet<TypeName> types();
+
+  @Override
+  public String toString() {
+    return Writables.writeToString(this);
+  }
+
+  @Override
+  public final Set<ClassName> referencedClasses() {
+    return FluentIterable.from(types())
+        .transformAndConcat(
+            new Function<TypeName, Set<ClassName>>() {
+              @Override
+              public Set<ClassName> apply(TypeName input) {
+                return input.referencedClasses();
+              }
+            })
+        .toSet();
+  }
+
+  private static final class BasicSnippet extends Snippet {
+    final String format;
+    final ImmutableSet<TypeName> types;
+    final ImmutableList<Object> args;
+
+    BasicSnippet(String format, ImmutableSet<TypeName> types, ImmutableList<Object> args) {
+      this.format = format;
+      this.types = types;
+      this.args = args;
+    }
+
+    @Override
+    ImmutableSet<TypeName> types() {
+      return types;
+    }
+
+    @Override
+    public Appendable write(Appendable appendable, Context context) throws IOException {
+      ImmutableList.Builder<Object> formattedArgsBuilder = ImmutableList.builder();
+      for (Object arg : args) {
+        if (arg instanceof Writable) {
+          formattedArgsBuilder.add(((Writable) arg).write(new StringBuilder(), context).toString());
+        } else {
+          formattedArgsBuilder.add(arg);
+        }
+      }
+
+      @SuppressWarnings("resource") // intentionally don't close the formatter
+      Formatter formatter = new Formatter(appendable);
+      formatter.format(format, Iterables.toArray(formattedArgsBuilder.build(), Object.class));
+
+      return appendable;
+    }
+  }
+
+  private static final class CompoundSnippet extends Snippet {
+    final String joinToken;
+    final ImmutableList<Snippet> snippets;
+
+    CompoundSnippet(String joinToken, ImmutableList<Snippet> snippets) {
+      this.joinToken = joinToken;
+      this.snippets = snippets;
+    }
+
+    @Override
+    ImmutableSet<TypeName> types() {
+      return FluentIterable.from(snippets)
+          .transformAndConcat(
+              new Function<Snippet, Iterable<TypeName>>() {
+                @Override
+                public Iterable<TypeName> apply(Snippet input) {
+                  return input.types();
+                }
+              })
+          .toSet();
+    }
+
+    @Override
+    public Appendable write(Appendable appendable, Context context) throws IOException {
+      Iterator<Snippet> snippetIterator = snippets.iterator();
+      if (snippetIterator.hasNext()) {
+        Snippet firstSnippet = snippetIterator.next();
+        firstSnippet.write(appendable, context);
+        while (snippetIterator.hasNext()) {
+          Snippet nextSnippet = snippetIterator.next();
+          appendable.append(joinToken);
+          nextSnippet.write(appendable, context);
+        }
+      }
+      return appendable;
+    }
+  }
+
+  public static Snippet format(String format, Object... args) {
+    ImmutableSet.Builder<TypeName> types = ImmutableSet.builder();
+    for (Object arg : args) {
+      if (arg instanceof Snippet) {
+        types.addAll(((Snippet) arg).types());
+      }
+      if (arg instanceof TypeName) {
+        types.add((TypeName) arg);
+      }
+      if (arg instanceof HasTypeName) {
+        types.add(((HasTypeName) arg).name());
+      }
+    }
+    return new BasicSnippet(format, types.build(), ImmutableList.copyOf(args));
+  }
+
+  public static Snippet format(String format, Iterable<? extends Object> args) {
+    return format(format, Iterables.toArray(args, Object.class));
+  }
+
+  public static Snippet memberSelectSnippet(Iterable<? extends Object> selectors) {
+    return format(Joiner.on('.').join(Collections.nCopies(Iterables.size(selectors), "%s")),
+        selectors);
+  }
+
+  public static Snippet nullCheck(Object thingToCheck) {
+    return format("if (%s == null) { throw new NullPointerException(); } ", thingToCheck);
+  }
+
+  public static Snippet nullCheck(Object thingToCheck, String message) {
+    return format("if (%s == null) { throw new NullPointerException(%s); } ",
+        thingToCheck,
+        StringLiteral.forValue(message));
+  }
+
+  public static Snippet makeParametersSnippet(Iterable<Snippet> parameterSnippets) {
+    return join(", ", parameterSnippets);
+  }
+
+  /**
+   * A snippet that concatenates its arguments with each snippet separated by a new line.
+   */
+  public static Snippet concat(Iterable<Snippet> snippets) {
+    return join("\n", snippets);
+  }
+
+  /**
+   * A snippet that joins its arguments with {@code joiner}.
+   */
+  public static Snippet join(String joinToken, Iterable<Snippet> snippets) {
+    return new CompoundSnippet(joinToken, ImmutableList.copyOf(snippets));
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/StringLiteral.java b/compiler/src/main/java/dagger/internal/codegen/writer/StringLiteral.java
new file mode 100644
index 0000000..2d059f9
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/StringLiteral.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Square, Inc.
+ *
+ * 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.writer;
+
+import java.util.Formatter;
+
+/**
+ * Represents a string literal as found in Java source code.
+ */
+public final class StringLiteral {
+  /** Returns a new {@link StringLiteral} instance for the intended value of the literal. */
+  public static StringLiteral forValue(String value) {
+    return new StringLiteral(value, stringLiteral(value));
+  }
+
+  /** Returns the string literal representing {@code data}, including wrapping quotes. */
+  private static String stringLiteral(String value) {
+    StringBuilder result = new StringBuilder();
+    result.append('"');
+    for (int i = 0; i < value.length(); i++) {
+      char c = value.charAt(i);
+      switch (c) {
+        case '"':
+          result.append("\\\"");
+          break;
+        case '\\':
+          result.append("\\\\");
+          break;
+        case '\b':
+          result.append("\\b");
+          break;
+        case '\t':
+          result.append("\\t");
+          break;
+        case '\n':
+          result.append("\\n");
+          break;
+        case '\f':
+          result.append("\\f");
+          break;
+        case '\r':
+          result.append("\\r");
+          break;
+        default:
+          if (Character.isISOControl(c)) {
+            new Formatter(result).format("\\u%04x", (int) c);
+          } else {
+            result.append(c);
+          }
+      }
+    }
+    result.append('"');
+    return result.toString();
+  }
+
+  private final String value;
+  private final String literal;
+
+  private StringLiteral(String value, String literal) {
+    this.value = value;
+    this.literal = literal;
+  }
+
+  public String value() {
+    return value;
+  }
+
+  public String literal() {
+    return literal;
+  }
+
+  @Override
+  public String toString() {
+    return literal;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    } else if (obj instanceof StringLiteral) {
+      return this.value.equals(((StringLiteral) obj).value);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return value.hashCode();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/TypeName.java b/compiler/src/main/java/dagger/internal/codegen/writer/TypeName.java
new file mode 100644
index 0000000..e0daf53
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/TypeName.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+public interface TypeName extends HasClassReferences, Writable {
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/TypeNames.java b/compiler/src/main/java/dagger/internal/codegen/writer/TypeNames.java
new file mode 100644
index 0000000..4bc2347
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/TypeNames.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.NullType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+public final class TypeNames {
+  static final Function<TypeMirror, TypeName> FOR_TYPE_MIRROR =
+      new Function<TypeMirror, TypeName>() {
+        @Override public TypeName apply(TypeMirror input) {
+          return forTypeMirror(input);
+        }
+      };
+
+  public static TypeName forClass(Class<?> clazz) {
+    if (clazz.isPrimitive()) {
+      return PrimitiveName.forClass(clazz);
+    } else if (void.class.equals(clazz)) {
+      return VoidName.VOID;
+    } else if (clazz.isArray()) {
+      return new ArrayTypeName(forClass(clazz.getComponentType()));
+    } else {
+      return ClassName.fromClass(clazz);
+    }
+  }
+
+  public static TypeName forTypeMirror(TypeMirror mirror) {
+    return mirror.accept(new SimpleTypeVisitor6<TypeName, Void>() {
+      @Override
+      protected TypeName defaultAction(TypeMirror e, Void p) {
+        throw new IllegalArgumentException(e.toString());
+      }
+      
+      @Override
+      public TypeName visitTypeVariable(TypeVariable t, Void p) {
+        return TypeVariableName.fromTypeVariable(t);
+      }
+
+      @Override
+      public ArrayTypeName visitArray(ArrayType t, Void p) {
+        return new ArrayTypeName(t.getComponentType().accept(this, null));
+      }
+
+      @Override
+      public TypeName visitDeclared(DeclaredType t, Void p) {
+        return t.getTypeArguments().isEmpty()
+            ? ClassName.fromTypeElement((TypeElement) t.asElement())
+            : new ParameterizedTypeName(
+                ClassName.fromTypeElement((TypeElement) t.asElement()),
+                FluentIterable.from(t.getTypeArguments()).transform(FOR_TYPE_MIRROR));
+      }
+
+      @Override
+      public PrimitiveName visitPrimitive(PrimitiveType t, Void p) {
+        return PrimitiveName.forTypeMirror(t);
+      }
+
+      @Override
+      public WildcardName visitWildcard(WildcardType t, Void p) {
+        return WildcardName.forTypeMirror(t);
+      }
+
+      @Override
+      public NullName visitNull(NullType t, Void p) {
+        return NullName.NULL;
+      }
+
+      @Override
+      public TypeName visitNoType(NoType t, Void p) {
+        switch (t.getKind()) {
+          case VOID:
+            return VoidName.VOID;
+          case PACKAGE:
+            throw new IllegalArgumentException();
+          default:
+            throw new IllegalStateException();
+        }
+      }
+    }, null);
+  }
+
+  private TypeNames() {
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/TypeVariableName.java b/compiler/src/main/java/dagger/internal/codegen/writer/TypeVariableName.java
new file mode 100644
index 0000000..c6ee533
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/TypeVariableName.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+
+public final class TypeVariableName implements TypeName {
+  private final CharSequence name;
+  private final Iterable<? extends TypeName> extendsBounds;
+
+  TypeVariableName(CharSequence name, Iterable<? extends TypeName> extendsBounds) {
+    this.name = name;
+    this.extendsBounds = extendsBounds;
+  }
+
+  public CharSequence name() {
+    return name;
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    ImmutableSet.Builder<ClassName> builder = new ImmutableSet.Builder<ClassName>();
+    for (TypeName bound : extendsBounds) {
+      builder.addAll(bound.referencedClasses());
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    appendable.append(name);
+    if (!Iterables.isEmpty(extendsBounds)) {
+      appendable.append(" extends ");
+      Iterator<? extends TypeName> iter = extendsBounds.iterator();
+      iter.next().write(appendable, context);
+      while (iter.hasNext()) {
+        appendable.append(" & ");
+        iter.next().write(appendable, context);  
+      }
+    }
+    return appendable;
+  }
+
+  @Override
+  public String toString() {
+    return Writables.writeToString(this);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof TypeVariableName) {
+      TypeVariableName that = (TypeVariableName) obj;
+      return this.name.toString().equals(that.name.toString())
+          && this.extendsBounds.equals(that.extendsBounds);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(name, extendsBounds);
+  }
+
+  static TypeVariableName named(CharSequence name) {
+    return new TypeVariableName(name, ImmutableList.<TypeName>of());
+  }
+  
+  public static TypeVariableName fromTypeVariable(TypeVariable variable) {
+    // Note: We don't have any use right now for the bounds because these are references
+    // to the type & not the specification of the type itself.  We never generate
+    // code with type variables that include upper or lower bounds.
+    return named(variable.asElement().getSimpleName());
+  }
+
+  // TODO(sameb): Consider making this a whole different thing: TypeParameterName since it
+  // has different semantics than a TypeVariable (parameters only have upper bounds).
+  public static TypeVariableName fromTypeParameterElement(TypeParameterElement element) {
+    // We filter out bounds of type Object because those would just clutter the generated code.
+    Iterable<? extends TypeName> bounds =
+        FluentIterable.from(element.getBounds())
+            .filter(new Predicate<TypeMirror>() {
+              @Override public boolean apply(TypeMirror input) {
+                return !MoreTypes.isType(input) || !MoreTypes.isTypeOf(Object.class, input);
+              }
+            })
+            .transform(TypeNames.FOR_TYPE_MIRROR);
+    return new TypeVariableName(element.getSimpleName(), bounds);
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/TypeWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/TypeWriter.java
new file mode 100644
index 0000000..b13d083
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/TypeWriter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Only named types. Doesn't cover anonymous inner classes.
+ */
+public abstract class TypeWriter /* ha ha */ extends Modifiable
+    implements Writable, HasTypeName, HasClassReferences {
+  final ClassName name;
+  final List<TypeName> implementedTypes;
+  final List<MethodWriter> methodWriters;
+  final List<TypeWriter> nestedTypeWriters;
+  final Map<String, FieldWriter> fieldWriters;
+
+  TypeWriter(ClassName name) {
+    this.name = name;
+    this.implementedTypes = Lists.newArrayList();
+    this.methodWriters = Lists.newArrayList();
+    this.nestedTypeWriters = Lists.newArrayList();
+    this.fieldWriters = Maps.newLinkedHashMap();
+  }
+
+  @Override
+  public ClassName name() {
+    return name;
+  }
+
+  public MethodWriter addMethod(TypeWriter returnType, String name) {
+    MethodWriter methodWriter = new MethodWriter(returnType.name, name);
+    methodWriters.add(methodWriter);
+    return methodWriter;
+  }
+
+  public MethodWriter addMethod(TypeMirror returnType, String name) {
+    MethodWriter methodWriter =
+        new MethodWriter(TypeNames.forTypeMirror(returnType), name);
+    methodWriters.add(methodWriter);
+    return methodWriter;
+  }
+
+  public MethodWriter addMethod(TypeName returnType, String name) {
+    MethodWriter methodWriter = new MethodWriter(returnType, name);
+    methodWriters.add(methodWriter);
+    return methodWriter;
+  }
+
+  public MethodWriter addMethod(Class<?> returnType, String name) {
+    MethodWriter methodWriter =
+        new MethodWriter(ClassName.fromClass(returnType), name);
+    methodWriters.add(methodWriter);
+    return methodWriter;
+  }
+
+  public ClassWriter addNestedClass(String name) {
+    ClassWriter innerClassWriter = new ClassWriter(this.name.nestedClassNamed(name));
+    nestedTypeWriters.add(innerClassWriter);
+    return innerClassWriter;
+  }
+
+  public void addImplementedType(TypeName typeReference) {
+    implementedTypes.add(typeReference);
+  }
+
+  public void addImplementedType(TypeElement typeElement) {
+    implementedTypes.add(ClassName.fromTypeElement(typeElement));
+  }
+
+  public FieldWriter addField(Class<?> type, String name) {
+    return addField(ClassName.fromClass(type), name);
+  }
+
+  public FieldWriter addField(TypeElement type, String name) {
+    return addField(ClassName.fromTypeElement(type), name);
+  }
+
+  public FieldWriter addField(TypeName type, String name) {
+    String candidateName = name;
+    int differentiator = 1;
+    while (fieldWriters.containsKey(candidateName)) {
+      candidateName = name + differentiator;
+      differentiator++;
+    }
+    FieldWriter fieldWriter = new FieldWriter(type, candidateName);
+    fieldWriters.put(candidateName, fieldWriter);
+    return fieldWriter;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/VariableWriter.java b/compiler/src/main/java/dagger/internal/codegen/writer/VariableWriter.java
new file mode 100644
index 0000000..58ee1e4
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/VariableWriter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class VariableWriter extends Modifiable implements Writable, HasClassReferences {
+  private final TypeName type;
+  private final String name;
+
+  VariableWriter(TypeName type, String name) {
+    this.type = checkNotNull(type);
+    this.name = checkNotNull(name);
+  }
+
+  public TypeName type() {
+    return type;
+  }
+
+  public String name() {
+    return name;
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    writeAnnotations(appendable, context);
+    writeModifiers(appendable);
+    type.write(appendable, context);
+    return appendable.append(' ').append(name);
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
+        .append(annotations)
+        .append(type)
+        .transformAndConcat(HasClassReferences.COMBINER)
+        .toSet();
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/VoidName.java b/compiler/src/main/java/dagger/internal/codegen/writer/VoidName.java
new file mode 100644
index 0000000..f82a4ca
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/VoidName.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Set;
+
+public enum VoidName implements TypeName {
+  VOID;
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    return ImmutableSet.of();
+  }
+
+  @Override
+  public String toString() {
+    return "void";
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    return appendable.append("void");
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/WildcardName.java b/compiler/src/main/java/dagger/internal/codegen/writer/WildcardName.java
new file mode 100644
index 0000000..7756f93
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/WildcardName.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Set;
+import javax.lang.model.type.WildcardType;
+
+import static dagger.internal.codegen.writer.TypeNames.FOR_TYPE_MIRROR;
+
+public final class WildcardName implements TypeName {
+  private final Optional<TypeName> extendsBound;
+  private final Optional<TypeName> superBound;
+
+  WildcardName(Optional<TypeName> extendsBound,
+      Optional<TypeName> superBound) {
+    this.extendsBound = extendsBound;
+    this.superBound = superBound;
+  }
+
+  static WildcardName forTypeMirror(WildcardType mirror) {
+    return new WildcardName(
+        Optional.fromNullable(mirror.getExtendsBound()).transform(FOR_TYPE_MIRROR),
+        Optional.fromNullable(mirror.getSuperBound()).transform(FOR_TYPE_MIRROR));
+  }
+
+  @Override
+  public Set<ClassName> referencedClasses() {
+    ImmutableSet.Builder<ClassName> builder = new ImmutableSet.Builder<ClassName>();
+    if (extendsBound.isPresent()) {
+      builder.addAll(extendsBound.get().referencedClasses());
+    }
+    if (superBound.isPresent()) {
+      builder.addAll(superBound.get().referencedClasses());
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Appendable write(Appendable appendable, Context context) throws IOException {
+    appendable.append('?');
+    if (extendsBound.isPresent()) {
+      appendable.append(" extends ");
+      extendsBound.get().write(appendable, context);
+    }
+    if (superBound.isPresent()) {
+      appendable.append(" super ");
+      superBound.get().write(appendable, context);
+    }
+    return appendable;
+  }
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/Writable.java b/compiler/src/main/java/dagger/internal/codegen/writer/Writable.java
new file mode 100644
index 0000000..9a88f43
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/Writable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import java.io.IOException;
+import java.util.Set;
+
+interface Writable {
+  interface Context {
+    String sourceReferenceForClassName(ClassName className);
+    Context createSubcontext(Set<ClassName> newTypes);
+  }
+
+  Appendable write(Appendable appendable, Context context) throws IOException;
+}
diff --git a/compiler/src/main/java/dagger/internal/codegen/writer/Writables.java b/compiler/src/main/java/dagger/internal/codegen/writer/Writables.java
new file mode 100644
index 0000000..0186cbf
--- /dev/null
+++ b/compiler/src/main/java/dagger/internal/codegen/writer/Writables.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import dagger.internal.codegen.writer.Writable.Context;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+
+final class Writables {
+
+  /**
+   * Joins the writables by the given delimiter, writing out the
+   * prefix & suffix if there's at least one element.
+   */
+  static void join(String delimiter, Iterable<? extends Writable> writables,
+      String prefix, String suffix,
+      Appendable appendable, Context context) throws IOException {
+    Iterator<? extends Writable> iter = writables.iterator();
+    if (iter.hasNext()) {
+      appendable.append(prefix);
+      iter.next().write(appendable, context);
+      while (iter.hasNext()) {
+        appendable.append(delimiter);
+        iter.next().write(appendable, context);
+      }
+      appendable.append(suffix);
+    }
+  }
+
+  /** Joins the writables by the given delimiter. */
+  static void join(String delimiter, Iterable<? extends Writable> writables,
+      Appendable appendable, Context context) throws IOException {
+    join(delimiter, writables, "", "", appendable, context);
+  }
+
+  static Writable toStringWritable(final Object object) {
+    return new Writable() {
+      @Override
+      public Appendable write(Appendable appendable, Context context) throws IOException {
+        return appendable.append(object.toString());
+      }
+    };
+  }
+
+  private static final Context DEFAULT_CONTEXT = new Context() {
+    @Override
+    public String sourceReferenceForClassName(ClassName className) {
+      return className.canonicalName();
+    }
+
+    @Override
+    public Context createSubcontext(Set<ClassName> newTypes) {
+      throw new UnsupportedOperationException();
+    }
+  };
+
+  static String writeToString(Writable writable) {
+    StringBuilder builder = new StringBuilder();
+    try {
+      writable.write(builder, DEFAULT_CONTEXT);
+    } catch (IOException e) {
+      throw new AssertionError("StringBuilder doesn't throw IOException" + e);
+    }
+    return builder.toString();
+  }
+
+  private Writables() {
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/BindingFieldTest.java b/compiler/src/test/java/dagger/internal/codegen/BindingFieldTest.java
new file mode 100644
index 0000000..eaaa595
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/BindingFieldTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.Iterables;
+import com.google.testing.compile.CompilationRule;
+import dagger.MembersInjector;
+import dagger.internal.codegen.writer.ClassName;
+import dagger.internal.codegen.writer.ParameterizedTypeName;
+import dagger.internal.codegen.writer.TypeName;
+import dagger.internal.codegen.writer.TypeNames;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+/**
+ * Test case for {@link FrameworkField}.
+ */
+@RunWith(JUnit4.class)
+public class BindingFieldTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  private Elements elements;
+  private Types types;
+  private Key.Factory keyFactory;
+
+  @Before public void setUp() {
+    this.types = compilationRule.getTypes();
+    this.elements = compilationRule.getElements();
+    this.keyFactory = new Key.Factory(types, elements);
+  }
+
+  private ExecutableElement getXConstructor() {
+    TypeElement classElement = elements.getTypeElement(X.class.getCanonicalName());
+    return Iterables.getOnlyElement(
+        ElementFilter.constructorsIn(classElement.getEnclosedElements()));
+  }
+
+  @Test public void frameworkType() {
+    Key key = keyFactory.forInjectConstructorWithResolvedType(
+        getXConstructor().getEnclosingElement().asType());
+    TypeName xClass = TypeNames.forTypeMirror(key.type());
+    assertThat(FrameworkField.createWithTypeFromKey(Provider.class,
+            BindingKey.create(BindingKey.Kind.CONTRIBUTION, key), "test")
+        .frameworkType())
+        .isEqualTo(ParameterizedTypeName.create(
+            ClassName.fromClass(Provider.class), xClass));
+    assertThat(FrameworkField.createWithTypeFromKey(MembersInjector.class,
+            BindingKey.create(BindingKey.Kind.MEMBERS_INJECTION, key), "test")
+        .frameworkType())
+        .isEqualTo(ParameterizedTypeName.create(
+            ClassName.fromClass(MembersInjector.class), xClass));
+  }
+
+  @Test public void nameSuffix() {
+    Key key = keyFactory.forInjectConstructorWithResolvedType(
+        getXConstructor().getEnclosingElement().asType());
+    assertThat(FrameworkField.createWithTypeFromKey(Provider.class,
+            BindingKey.create(BindingKey.Kind.CONTRIBUTION, key), "foo").name())
+        .isEqualTo("fooProvider");
+    assertThat(FrameworkField.createWithTypeFromKey(Provider.class,
+            BindingKey.create(BindingKey.Kind.CONTRIBUTION, key), "fooProvider").name())
+        .isEqualTo("fooProvider");
+
+  }
+
+  static final class X {
+    @Inject X() {}
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ComponentBuilderTest.java b/compiler/src/test/java/dagger/internal/codegen/ComponentBuilderTest.java
new file mode 100644
index 0000000..cf0e69d
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ComponentBuilderTest.java
@@ -0,0 +1,941 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+/** Tests for {@link dagger.Component.Builder} */
+@RunWith(JUnit4.class)
+public class ComponentBuilderTest {
+
+  private static final ErrorMessages.ComponentBuilderMessages MSGS =
+      ErrorMessages.ComponentBuilderMessages.INSTANCE;
+
+  @Test
+  public void testEmptyBuilder() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "",
+        "  @Component.Builder",
+        "  static interface Builder {",
+        "     SimpleComponent build();",
+        "  }",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import test.SimpleComponent",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static SimpleComponent.Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return SomeInjectableType_Factory.create().get();",
+        "  }",
+        "",
+        "  private static final class Builder implements SimpleComponent.Builder {",
+        "    @Override",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(injectableTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void testUsesBuildAndSetterNames() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides String string() { return null; }",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  String string();",
+        "",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    Builder setTestModule(TestModule testModule);",
+        "    TestComponent create();",
+        "  }",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "import test.TestComponent;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<String> stringProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static TestComponent.Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().create();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.stringProvider = TestModule_StringFactory.create(builder.testModule);",
+        "  }",
+        "",
+        "  @Override",
+        "  public String string() {",
+        "    return stringProvider.get();",
+        "  }",
+        "",
+        "  private static final class Builder implements TestComponent.Builder {",
+        "    private TestModule testModule;",
+        "",
+        "    @Override",
+        "    public TestComponent create() {",
+        "      if (testModule == null) {",
+        "        this.testModule = new TestModule();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    @Override",
+        "    public Builder setTestModule(TestModule testModule) {",
+        "      if (testModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.testModule = testModule;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(moduleFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void testIgnoresModulesNotInApi() {
+    JavaFileObject module1 = JavaFileObjects.forSourceLines("test.TestModule1",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule1 {",
+        "  @Provides String string() { return null; }",
+        "}");
+    JavaFileObject module2 = JavaFileObjects.forSourceLines("test.TestModule2",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule2 {",
+        "  @Provides Integer integer() { return null; }",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = {TestModule1.class, TestModule2.class})",
+        "interface TestComponent {",
+        "  String string();",
+        "  Integer integer();",
+        "",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    Builder testModule1(TestModule1 testModule1);",
+        "    TestComponent build();",
+        "  }",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "import test.TestComponent;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<String> stringProvider;",
+        "  private Provider<Integer> integerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static TestComponent.Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.stringProvider = TestModule1_StringFactory.create(builder.testModule1);",
+        "    this.integerProvider = TestModule2_IntegerFactory.create(builder.testModule2);",
+        "  }",
+        "",
+        "  @Override",
+        "  public String string() {",
+        "    return stringProvider.get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Integer integer() {",
+        "    return integerProvider.get();",
+        "  }",
+        "",
+        "  private static final class Builder implements TestComponent.Builder {",
+        "    private TestModule1 testModule1;",
+        "    private TestModule2 testModule2;",
+        "",
+        "    @Override",
+        "    public TestComponent build() {",
+        "      if (testModule1 == null) {",
+        "        this.testModule1 = new TestModule1();",
+        "      }",
+        "      if (testModule2 == null) {",
+        "        this.testModule2 = new TestModule2();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    @Override",
+        "    public Builder testModule1(TestModule1 testModule1) {",
+        "      if (testModule1 == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.testModule1 = testModule1;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(module1, module2, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void testMoreThanOneBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  @Component.Builder",
+        "  static interface Builder {",
+        "     SimpleComponent build();",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder2 {",
+        "     SimpleComponent build();",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.moreThanOne(),
+            "[test.SimpleComponent.Builder, test.SimpleComponent.Builder2]"))
+        .in(componentFile);
+  }
+
+  @Test
+  public void testBuilderGenericsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder<T> {",
+        "     SimpleComponent build();",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.generics())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testBuilderNotInComponentFails() {
+    JavaFileObject builder = JavaFileObjects.forSourceLines("test.Builder",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component.Builder",
+        "interface Builder {}");
+    assertAbout(javaSource()).that(builder)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeInComponent())
+        .in(builder);
+  }
+
+  @Test
+  public void testBuilderMissingBuildMethodFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.missingBuildMethod())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testPrivateBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  private interface Builder {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.isPrivate())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testNonStaticBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  abstract class Builder {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeStatic())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testNonAbstractBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  static class Builder {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeAbstract());
+  }
+
+  @Test
+  public void testBuilderOneCxtorWithArgsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  static abstract class Builder {",
+        "    Builder(String unused) {}",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testBuilderMoreThanOneCxtorFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  static abstract class Builder {",
+        "    Builder() {}",
+        "    Builder(String unused) {}",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testBuilderEnumFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  enum Builder {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeClassOrInterface())
+        .in(componentFile);
+  }
+
+  @Test
+  public void testBuilderBuildReturnsWrongTypeFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    String build();",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.buildMustReturnComponentType())
+            .in(componentFile).onLine(11);
+  }
+
+  @Test
+  public void testInheritedBuilderBuildReturnsWrongTypeFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent {",
+        "    String build();",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedBuildMustReturnComponentType(), "build"))
+            .in(componentFile).onLine(14);
+  }
+
+  @Test
+  public void testTwoBuildMethodsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    SimpleComponent create();",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.twoBuildMethods(), "build()"))
+            .in(componentFile).onLine(12);
+  }
+
+  @Test
+  public void testInheritedTwoBuildMethodsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent {",
+        "    SimpleComponent build();",
+        "    SimpleComponent create();",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedTwoBuildMethods(), "create()", "build()"))
+            .in(componentFile).onLine(15);
+  }
+
+  @Test
+  public void testMoreThanOneArgFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    Builder set(String s, Integer i);",
+        "    Builder set(Number n, Double d);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMustTakeOneArg())
+            .in(componentFile).onLine(12)
+        .and().withErrorContaining(MSGS.methodsMustTakeOneArg())
+            .in(componentFile).onLine(13);
+  }
+
+  @Test
+  public void testInheritedMoreThanOneArgFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent {",
+        "    SimpleComponent build();",
+        "    Builder set1(String s, Integer i);",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMustTakeOneArg(),
+                "set1(java.lang.String,java.lang.Integer)"))
+            .in(componentFile).onLine(15);
+  }
+
+  @Test
+  public void testSetterReturningNonVoidOrBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    String set(Integer i);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMustReturnVoidOrBuilder())
+            .in(componentFile).onLine(12);
+  }
+
+  @Test
+  public void testInheritedSetterReturningNonVoidOrBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent {",
+        "    SimpleComponent build();",
+        "    String set(Integer i);",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMustReturnVoidOrBuilder(),
+                "set(java.lang.Integer)"))
+            .in(componentFile).onLine(15);
+  }
+
+  @Test
+  public void testGenericsOnSetterMethodFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    <T> Builder set(T t);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMayNotHaveTypeParameters())
+            .in(componentFile).onLine(12);
+  }
+
+  @Test
+  public void testGenericsOnInheritedSetterMethodFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent {",
+        "    SimpleComponent build();",
+        "    <T> Builder set(T t);",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)"))
+            .in(componentFile).onLine(15);
+  }
+
+  @Test
+  public void testMultipleSettersPerTypeFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    void set1(String s);",
+        "    void set2(String s);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.manyMethodsForType(),
+                  "java.lang.String", "[set1(java.lang.String), set2(java.lang.String)]"))
+            .in(componentFile).onLine(10);
+  }
+
+  @Test
+  public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  interface Parent<T> {",
+        "    void set1(T t);",
+        "  }",
+        "",
+        "  @Component.Builder",
+        "  interface Builder extends Parent<String> {",
+        "    SimpleComponent build();",
+        "    void set2(String s);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.manyMethodsForType(),
+                  "java.lang.String", "[set1(T), set2(java.lang.String)]"))
+            .in(componentFile).onLine(14);
+  }
+
+  @Test
+  public void testExtraSettersFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "abstract class SimpleComponent {",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    SimpleComponent build();",
+        "    void set1(String s);",
+        "    void set2(Integer s);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.extraSetters(),
+                  "[void test.SimpleComponent.Builder.set1(String),"
+                  + " void test.SimpleComponent.Builder.set2(Integer)]"))
+            .in(componentFile).onLine(10);
+
+  }
+
+  @Test
+  public void testMissingSettersFail() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  TestModule(String unused) {}",
+        "  @Provides String s() { return null; }",
+        "}");
+    JavaFileObject module2File = JavaFileObjects.forSourceLines("test.Test2Module",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class Test2Module {",
+        "  @Provides Integer i() { return null; }",
+        "}");
+    JavaFileObject module3File = JavaFileObjects.forSourceLines("test.Test3Module",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class Test3Module {",
+        "  Test3Module(String unused) {}",
+        "  @Provides Double d() { return null; }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = {TestModule.class, Test2Module.class, Test3Module.class},",
+        "           dependencies = OtherComponent.class)",
+        "interface TestComponent {",
+        "  String string();",
+        "  Integer integer();",
+        "",
+        "  @Component.Builder",
+        "  interface Builder {",
+        "    TestComponent create();",
+        "  }",
+        "}");
+    JavaFileObject otherComponent = JavaFileObjects.forSourceLines("test.OtherComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface OtherComponent {}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(moduleFile, module2File, module3File, componentFile, otherComponent))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            // Ignores Test2Module because we can construct it ourselves.
+            // TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies.
+            String.format(MSGS.missingSetters(),
+                "[test.TestModule, test.Test3Module, test.OtherComponent]"))
+            .in(componentFile).onLine(12);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java b/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java
new file mode 100644
index 0000000..28e3b45
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java
@@ -0,0 +1,2185 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.testing.compile.JavaFileObjects;
+import dagger.internal.codegen.writer.StringLiteral;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static dagger.internal.codegen.ErrorMessages.REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT;
+import static javax.tools.StandardLocation.SOURCE_OUTPUT;
+
+@RunWith(JUnit4.class)
+public class ComponentProcessorTest {
+  private static final StringLiteral NPE_LITERAL =
+      StringLiteral.forValue(ErrorMessages.CANNOT_RETURN_NULL_FROM_NON_NULLABLE_COMPONENT_METHOD);
+
+  @Test public void componentOnConcreteClass() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "final class NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void componentOnEnum() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "enum NotAComponent {",
+        "  INSTANCE",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void componentOnAnnotation() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "@interface NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void nonModuleModule() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = Object.class)",
+        "interface NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("is not annotated with @Module");
+  }
+
+  private void checkCannotReferToModuleOfType(String moduleType) {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        moduleType + " TestModule {}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.BadComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface BadComponent {}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT, "test.TestModule"));
+  }
+
+  @Test public void cannotReferToAbstractClassModules() {
+    checkCannotReferToModuleOfType("abstract class");
+  }
+
+  @Test public void cannotReferToInterfaceModules() {
+    checkCannotReferToModuleOfType("interface");
+  }
+
+  @Test public void doubleBindingFromResolvedModules() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.ParentModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.List;",
+        "",
+        "@Module",
+        "abstract class ParentModule<A> {",
+        "  @Provides List<A> provideListB(A a) { return null; }",
+        "}");
+    JavaFileObject child = JavaFileObjects.forSourceLines("test.ChildModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class ChildNumberModule extends ParentModule<Integer> {",
+        "  @Provides Integer provideInteger() { return null; }",
+        "}");
+    JavaFileObject another = JavaFileObjects.forSourceLines("test.AnotherModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.List;",
+        "",
+        "@Module",
+        "class AnotherModule {",
+        "  @Provides List<Integer> provideListOfInteger() { return null; }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.BadComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.List;",
+        "",
+        "@Component(modules = {ChildNumberModule.class, AnotherModule.class})",
+        "interface BadComponent {",
+        "  List<Integer> listOfInteger();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(parent, child, another, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile().withErrorContaining(
+            "java.util.List<java.lang.Integer> is bound multiple times")
+        .and().withErrorContaining(
+            "@Provides List<Integer> test.ChildNumberModule.provideListB(Integer)")
+        .and().withErrorContaining(
+            "@Provides List<Integer> test.AnotherModule.provideListOfInteger()");
+  }
+
+  @Test public void simpleComponent() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "  Lazy<SomeInjectableType> lazySomeInjectableType();",
+        "  Provider<SomeInjectableType> someInjectableTypeProvider();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Lazy;",
+        "import dagger.internal.DoubleCheckLazy;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return SomeInjectableType_Factory.create().get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Lazy<SomeInjectableType> lazySomeInjectableType() {",
+        "    return DoubleCheckLazy.create(SomeInjectableType_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public Provider<SomeInjectableType> someInjectableTypeProvider() {",
+        "    return SomeInjectableType_Factory.create();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(injectableTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void componentWithScope() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "import javax.inject.Provider;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "  Lazy<SomeInjectableType> lazySomeInjectableType();",
+        "  Provider<SomeInjectableType> someInjectableTypeProvider();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Lazy;",
+        "import dagger.internal.DoubleCheckLazy;",
+        "import dagger.internal.ScopedProvider;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private Provider<SomeInjectableType> someInjectableTypeProvider;",
+        "",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.someInjectableTypeProvider =",
+        "        ScopedProvider.create(SomeInjectableType_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return someInjectableTypeProvider.get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Lazy<SomeInjectableType> lazySomeInjectableType() {",
+        "    return DoubleCheckLazy.create(someInjectableTypeProvider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public Provider<SomeInjectableType> someInjectableTypeProvider() {",
+        "    return someInjectableTypeProvider;",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(injectableTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void simpleComponentWithNesting() {
+    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines("test.OuterType",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Inject;",
+        "",
+        "final class OuterType {",
+        "  static class A {",
+        "    @Inject A() {}",
+        "  }",
+        "  static class B {",
+        "    @Inject A a;",
+        "  }",
+        "  @Component interface SimpleComponent {",
+        "    A a();",
+        "    void inject(B b);",
+        "  }",
+        "}");
+
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerOuterType_SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import test.OuterType.A;",
+        "import test.OuterType.B;",
+        "import test.OuterType.SimpleComponent;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerOuterType_SimpleComponent implements SimpleComponent {",
+        "  private MembersInjector<B> bMembersInjector;",
+        "",
+        "  private DaggerOuterType_SimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.bMembersInjector =",
+        "        OuterType$B_MembersInjector.create(OuterType$A_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public A a() {",
+        "    return OuterType$A_Factory.create().get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public void inject(B b) {",
+        "    bMembersInjector.injectMembers(b);",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerOuterType_SimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(nestedTypesFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void componentWithModule() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A(B b) {}",
+        "}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "interface B {}");
+    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class C {",
+        "  @Inject C() {}",
+        "}");
+
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides B b(C c) { return null; }",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  A a();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<B> bProvider;",
+        "  private Provider<A> aProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.bProvider = TestModule_BFactory.create(builder.testModule,",
+        "        C_Factory.create());",
+        "    this.aProvider = A_Factory.create(bProvider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public A a() {",
+        "    return aProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private TestModule testModule;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (testModule == null) {",
+        "        this.testModule = new TestModule();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder testModule(TestModule testModule) {",
+        "      if (testModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.testModule = testModule;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aFile, bFile, cFile, moduleFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void transitiveModuleDeps() {
+    JavaFileObject always = JavaFileObjects.forSourceLines("test.AlwaysIncluded",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "final class AlwaysIncluded {}");
+    JavaFileObject testModule = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = {DepModule.class, AlwaysIncluded.class})",
+        "final class TestModule extends ParentTestModule {}");
+    JavaFileObject parentTest = JavaFileObjects.forSourceLines("test.ParentTestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = {ParentTestIncluded.class, AlwaysIncluded.class})",
+        "class ParentTestModule {}");
+    JavaFileObject parentTestIncluded = JavaFileObjects.forSourceLines("test.ParentTestIncluded",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = AlwaysIncluded.class)",
+        "final class ParentTestIncluded {}");
+    JavaFileObject depModule = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = {RefByDep.class, AlwaysIncluded.class})",
+        "final class DepModule extends ParentDepModule {}");
+    JavaFileObject refByDep = JavaFileObjects.forSourceLines("test.RefByDep",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = AlwaysIncluded.class)",
+        "final class RefByDep extends ParentDepModule {}");
+    JavaFileObject parentDep = JavaFileObjects.forSourceLines("test.ParentDepModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = {ParentDepIncluded.class, AlwaysIncluded.class})",
+        "class ParentDepModule {}");
+    JavaFileObject parentDepIncluded = JavaFileObjects.forSourceLines("test.ParentDepIncluded",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = AlwaysIncluded.class)",
+        "final class ParentDepIncluded {}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "}");
+    // Generated code includes all includes, but excludes the parent modules.
+    // The "always" module should only be listed once.
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder testModule(TestModule testModule) {",
+        "      if (testModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder parentTestIncluded(ParentTestIncluded parentTestIncluded) {",
+        "      if (parentTestIncluded == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder alwaysIncluded(AlwaysIncluded alwaysIncluded) {",
+        "      if (alwaysIncluded == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder depModule(DepModule depModule) {",
+        "      if (depModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder parentDepIncluded(ParentDepIncluded parentDepIncluded) {",
+        "      if (parentDepIncluded == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "",
+        "    @Deprecated",
+        "    public Builder refByDep(RefByDep refByDep) {",
+        "      if (refByDep == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(always,
+            testModule,
+            parentTest,
+            parentTestIncluded,
+            depModule,
+            refByDep,
+            parentDep,
+            parentDepIncluded,
+            componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void generatedTransitiveModule() {
+    JavaFileObject rootModule = JavaFileObjects.forSourceLines("test.RootModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = GeneratedModule.class)",
+        "final class RootModule {}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = RootModule.class)",
+        "interface TestComponent {}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(rootModule, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(rootModule, component))
+        .processedWith(
+            new ComponentProcessor(),
+            new GeneratingProcessor(
+                "test.GeneratedModule",
+                "package test;",
+                "",
+                "import dagger.Module;",
+                "",
+                "@Module",
+                "final class GeneratedModule {}"))
+        .compilesWithoutError();
+  }
+
+  @Test
+  public void generatedModuleInSubcomponent() {
+    JavaFileObject subcomponent =
+        JavaFileObjects.forSourceLines(
+            "test.ChildComponent",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "",
+            "@Subcomponent(modules = GeneratedModule.class)",
+            "interface ChildComponent {}");
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component",
+            "interface TestComponent {",
+            "  ChildComponent childComponent();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(subcomponent, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(subcomponent, component))
+        .processedWith(
+            new ComponentProcessor(),
+            new GeneratingProcessor(
+                "test.GeneratedModule",
+                "package test;",
+                "",
+                "import dagger.Module;",
+                "",
+                "@Module",
+                "final class GeneratedModule {}"))
+        .compilesWithoutError();
+  }
+
+  @Test
+  public void subcomponentOmitsInheritedBindings() {
+    JavaFileObject parent =
+        JavaFileObjects.forSourceLines(
+            "test.Parent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component(modules = ParentModule.class)",
+            "interface Parent {",
+            "  Child child();",
+            "}");
+    JavaFileObject parentModule =
+        JavaFileObjects.forSourceLines(
+            "test.ParentModule",
+            "package test;",
+            "",
+            "import dagger.mapkeys.StringKey;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "",
+            "import static dagger.Provides.Type.SET;",
+            "import static dagger.Provides.Type.MAP;",
+            "",
+            "@Module",
+            "class ParentModule {",
+            "  @Provides(type = SET) static Object parentObject() {",
+            "    return \"parent object\";",
+            "  }",
+            "",
+            "  @Provides(type = MAP) @StringKey(\"parent key\") Object parentKeyObject() {",
+            "    return \"parent value\";",
+            "  }",
+            "}");
+    JavaFileObject child =
+        JavaFileObjects.forSourceLines(
+            "test.Child",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "import java.util.Map;",
+            "import java.util.Set;",
+            "",
+            "@Subcomponent",
+            "interface Child {",
+            "  Set<Object> objectSet();",
+            "  Map<String, Object> objectMap();",
+            "}");
+    JavaFileObject expected =
+        JavaFileObjects.forSourceLines(
+            "test.DaggerParent",
+            "package test;",
+            "",
+            "import dagger.internal.MapFactory;",
+            "import dagger.internal.MapProviderFactory;",
+            "import dagger.internal.SetFactory;",
+            "import java.util.Map;",
+            "import java.util.Set;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class DaggerParent implements Parent {",
+            "  private Provider<Set<Object>> setOfObjectContribution1Provider;",
+            "  private Provider<Set<Object>> setOfObjectProvider;",
+            "  private Provider<Object> mapOfStringAndProviderOfObjectContribution1;",
+            "  private Provider<Map<String, Provider<Object>>>",
+            "      mapOfStringAndProviderOfObjectProvider;",
+            "",
+            "  private DaggerParent(Builder builder) {",
+            "    assert builder != null;",
+            "    initialize(builder);",
+            "  }",
+            "",
+            "  public static Builder builder() {",
+            "    return new Builder();",
+            "  }",
+            "",
+            "  public static Parent create() {",
+            "    return builder().build();",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\")",
+            "  private void initialize(final Builder builder) {",
+            "    this.setOfObjectContribution1Provider =",
+            "        ParentModule_ParentObjectFactory.create();",
+            "    this.setOfObjectProvider = SetFactory.create(setOfObjectContribution1Provider);",
+            "    this.mapOfStringAndProviderOfObjectContribution1 =",
+            "        ParentModule_ParentKeyObjectFactory.create(builder.parentModule);",
+            "    this.mapOfStringAndProviderOfObjectProvider =",
+            "        MapProviderFactory.<String, Object>builder(1)",
+            "            .put(\"parent key\", mapOfStringAndProviderOfObjectContribution1)",
+            "            .build();",
+            "  }",
+            "",
+            "  @Override",
+            "  public Child child() {",
+            "    return new ChildImpl();",
+            "  }",
+            "",
+            "  public static final class Builder {",
+            "    private ParentModule parentModule;",
+            "",
+            "    private Builder() {}",
+            "",
+            "    public Parent build() {",
+            "      if (parentModule == null) {",
+            "        this.parentModule = new ParentModule();",
+            "      }",
+            "      return new DaggerParent(this);",
+            "    }",
+            "",
+            "    public Builder parentModule(ParentModule parentModule) {",
+            "      if (parentModule == null) {",
+            "        throw new NullPointerException();",
+            "      }",
+            "      this.parentModule = parentModule;",
+            "      return this;",
+            "    }",
+            "  }",
+            "",
+            "  private final class ChildImpl implements Child {",
+            "    private Provider<Map<String, Object>> mapOfStringAndObjectProvider;",
+            "",
+            "    private ChildImpl() {",
+            "      initialize();",
+            "    }",
+            "",
+            "    @SuppressWarnings(\"unchecked\")",
+            "    private void initialize() {",
+            "      this.mapOfStringAndObjectProvider = MapFactory.create(",
+            "          DaggerParent.this.mapOfStringAndProviderOfObjectProvider);",
+            "    }",
+            "",
+            "    @Override",
+            "    public Set<Object> objectSet() {",
+            "      return DaggerParent.this.setOfObjectProvider.get();",
+            "    }",
+            "",
+            "    @Override",
+            "    public Map<String, Object> objectMap() {",
+            "      return mapOfStringAndObjectProvider.get();",
+            "    }",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(parent, parentModule, child))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test public void testDefaultPackage() {
+    JavaFileObject aClass = JavaFileObjects.forSourceLines("AClass", "class AClass {}");
+    JavaFileObject bClass = JavaFileObjects.forSourceLines("BClass",
+        "import javax.inject.Inject;",
+        "",
+        "class BClass {",
+        "  @Inject BClass(AClass a) {}",
+        "}");
+    JavaFileObject aModule = JavaFileObjects.forSourceLines("AModule",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module class AModule {",
+        "  @Provides AClass aClass() {",
+        "    return new AClass();",
+        "  }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("SomeComponent",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = AModule.class)",
+        "interface SomeComponent {",
+        "  BClass bClass();",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aModule, aClass, bClass, component))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void setBindings() {
+    JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET_VALUES;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.Collections;",
+        "import java.util.Set;",
+        "",
+        "@Module",
+        "final class EmptySetModule {",
+        "  @Provides(type = SET_VALUES) Set<String> emptySet() { return Collections.emptySet(); }",
+        "}");
+    JavaFileObject setModuleFile = JavaFileObjects.forSourceLines("test.SetModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class SetModule {",
+        "  @Provides(type = SET) String string() { return \"\"; }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Set;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {EmptySetModule.class, SetModule.class})",
+        "interface TestComponent {",
+        "  Set<String> strings();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.SetFactory;",
+        "import java.util.Set;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Set<String>> setOfStringContribution1Provider;",
+        "  private Provider<Set<String>> setOfStringContribution2Provider;",
+        "  private Provider<Set<String>> setOfStringProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.setOfStringContribution1Provider =",
+        "        EmptySetModule_EmptySetFactory.create(builder.emptySetModule);",
+        "    this.setOfStringContribution2Provider =",
+        "        SetModule_StringFactory.create(builder.setModule);",
+        "    this.setOfStringProvider = SetFactory.create(",
+        "        setOfStringContribution1Provider, setOfStringContribution2Provider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public Set<String> strings() {",
+        "    return setOfStringProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private EmptySetModule emptySetModule;",
+        "    private SetModule setModule;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (emptySetModule == null) {",
+        "        this.emptySetModule = new EmptySetModule();",
+        "      }",
+        "      if (setModule == null) {",
+        "        this.setModule = new SetModule();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder emptySetModule(EmptySetModule emptySetModule) {",
+        "      if (emptySetModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.emptySetModule = emptySetModule;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder setModule(SetModule setModule) {",
+        "      if (setModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.setModule = setModule;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(emptySetModuleFile, setModuleFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void membersInjection() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject injectedTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectedType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectedType {",
+        "  @Inject SomeInjectableType injectedField;",
+        "  SomeInjectedType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  void inject(SomeInjectedType instance);",
+        "  SomeInjectedType injectAndReturn(SomeInjectedType instance);",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private MembersInjector<SomeInjectedType> someInjectedTypeMembersInjector;",
+        "",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.someInjectedTypeMembersInjector =",
+        "        SomeInjectedType_MembersInjector.create(SomeInjectableType_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public void inject(SomeInjectedType instance) {",
+        "    someInjectedTypeMembersInjector.injectMembers(instance);",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectedType injectAndReturn(SomeInjectedType instance) {",
+        "    someInjectedTypeMembersInjector.injectMembers(instance);",
+        "    return instance;",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(injectableTypeFile, injectedTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void componentInjection() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType(SimpleComponent component) {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.internal.InstanceFactory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private Provider<SimpleComponent> simpleComponentProvider;",
+        "  private Provider<SomeInjectableType> someInjectableTypeProvider;",
+        "",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.simpleComponentProvider = InstanceFactory.<SimpleComponent>create(this);",
+        "    this.someInjectableTypeProvider =",
+        "        SomeInjectableType_Factory.create(simpleComponentProvider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return someInjectableTypeProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(injectableTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void membersInjectionInsideProvision() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject injectedTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectedType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectedType {",
+        "  @Inject SomeInjectableType injectedField;",
+        "  @Inject SomeInjectedType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectedType createAndInject();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private MembersInjector<SomeInjectedType> someInjectedTypeMembersInjector;",
+        "  private Provider<SomeInjectedType> someInjectedTypeProvider;",
+        "",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.someInjectedTypeMembersInjector =",
+        "        SomeInjectedType_MembersInjector.create(SomeInjectableType_Factory.create());",
+        "    this.someInjectedTypeProvider =",
+        "        SomeInjectedType_Factory.create(someInjectedTypeMembersInjector);",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectedType createAndInject() {",
+        "    return someInjectedTypeProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(injectableTypeFile, injectedTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void injectionWithGenericBaseClass() {
+    JavaFileObject genericType = JavaFileObjects.forSourceLines("test.AbstractGenericType",
+        "package test;",
+        "",
+        "abstract class AbstractGenericType<T> {",
+        "}");
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType extends AbstractGenericType<String> {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.MembersInjectors;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private Provider<SomeInjectableType> someInjectableTypeProvider;",
+        "",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.someInjectableTypeProvider =",
+        "        SomeInjectableType_Factory.create((MembersInjector) MembersInjectors.noOp());",
+        "  }",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return someInjectableTypeProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(genericType, injectableTypeFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void componentDependency() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A() {}",
+        "}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class B {",
+        "  @Inject B(A a) {}",
+        "}");
+    JavaFileObject aComponentFile = JavaFileObjects.forSourceLines("test.AComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface AComponent {",
+        "  A a();",
+        "}");
+    JavaFileObject bComponentFile = JavaFileObjects.forSourceLines("test.AComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(dependencies = AComponent.class)",
+        "interface BComponent {",
+        "  B b();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerBComponent",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerBComponent implements BComponent {",
+        "  private Provider<A> aProvider;",
+        "  private Provider<B> bProvider;",
+        "",
+        "  private DaggerBComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.aProvider = new Factory<A>() {",
+        "      private final AComponent aComponent = builder.aComponent;",
+        "      @Override public A get() {",
+        "        A provided = aComponent.a();",
+        "        if (provided == null) {",
+        "          throw new NullPointerException(" + NPE_LITERAL + ");",
+        "        }",
+        "        return provided;",
+        "      }",
+        "    };",
+        "    this.bProvider = B_Factory.create(aProvider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public B b() {",
+        "    return bProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private AComponent aComponent;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public BComponent build() {",
+        "      if (aComponent == null) {",
+        "        throw new IllegalStateException(AComponent.class.getCanonicalName()",
+        "            + \" must be set\");",
+        "      }",
+        "      return new DaggerBComponent(this);",
+        "    }",
+        "",
+        "    public Builder aComponent(AComponent aComponent) {",
+        "      if (aComponent == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.aComponent = aComponent;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aFile, bFile, aComponentFile, bComponentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void moduleNameCollision() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "public final class A {}");
+    JavaFileObject otherAFile = JavaFileObjects.forSourceLines("other.test.A",
+        "package other.test;",
+        "",
+        "public final class A {}");
+
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "public final class TestModule {",
+        "  @Provides A a() { return null; }",
+        "}");
+    JavaFileObject otherModuleFile = JavaFileObjects.forSourceLines("other.test.TestModule",
+        "package other.test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "public final class TestModule {",
+        "  @Provides A a() { return null; }",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {TestModule.class, other.test.TestModule.class})",
+        "interface TestComponent {",
+        "  A a();",
+        "  other.test.A otherA();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "import other.test.A;",
+        "import other.test.TestModule;",
+        "import other.test.TestModule_AFactory;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<test.A> aProvider;",
+        "  private Provider<A> aProvider1;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.aProvider = test.TestModule_AFactory.create(builder.testModule);",
+        "    this.aProvider1 = TestModule_AFactory.create(builder.testModule1);",
+        "  }",
+        "",
+        "  @Override",
+        "  public test.A a() {",
+        "    return aProvider.get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public A otherA() {",
+        "    return aProvider1.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private test.TestModule testModule;",
+        "    private TestModule testModule1;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (testModule == null) {",
+        "        this.testModule = new test.TestModule();",
+        "      }",
+        "      if (testModule1 == null) {",
+        "        this.testModule1 = new TestModule();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder testModule(test.TestModule testModule) {",
+        "      if (testModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.testModule = testModule;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder testModule(TestModule testModule) {",
+        "      if (testModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.testModule1 = testModule;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aFile, otherAFile, moduleFile, otherModuleFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void resolutionOrder() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A(B b) {}",
+        "}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class B {",
+        "  @Inject B(C c) {}",
+        "}");
+    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class C {",
+        "  @Inject C() {}",
+        "}");
+    JavaFileObject xFile = JavaFileObjects.forSourceLines("test.X",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class X {",
+        "  @Inject X(C c) {}",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  A a();",
+        "  C c();",
+        "  X x();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<B> bProvider;",
+        "  private Provider<A> aProvider;",
+        "  private Provider<X> xProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.bProvider = B_Factory.create(C_Factory.create());",
+        "    this.aProvider = A_Factory.create(bProvider);",
+        "    this.xProvider = X_Factory.create(C_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public A a() {",
+        "    return aProvider.get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public C c() {",
+        "    return C_Factory.create().get();",
+        "  }",
+        "",
+        "  @Override",
+        "  public X x() {",
+        "    return xProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aFile, bFile, cFile, xFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void simpleComponent_redundantComponentMethod() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentSupertypeAFile = JavaFileObjects.forSourceLines("test.SupertypeA",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SupertypeA {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject componentSupertypeBFile = JavaFileObjects.forSourceLines("test.SupertypeB",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SupertypeB {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent extends SupertypeA, SupertypeB {",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {}",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return SomeInjectableType_Factory.create().get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(
+            injectableTypeFile, componentSupertypeAFile, componentSupertypeBFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void simpleComponent_inheritedComponentMethodDep() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType() {}",
+        "}");
+    JavaFileObject componentSupertype = JavaFileObjects.forSourceLines("test.Supertype",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface Supertype {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject depComponentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent extends Supertype {",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ComponentWithDep",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(dependencies = SimpleComponent.class)",
+        "interface ComponentWithDep {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerSimpleComponent",
+        "package test;",
+        "",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerSimpleComponent implements SimpleComponent {",
+        "  private DaggerSimpleComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static SimpleComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {}",
+        "",
+        "  @Override",
+        "  public SomeInjectableType someInjectableType() {",
+        "    return SomeInjectableType_Factory.create().get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public SimpleComponent build() {",
+        "      return new DaggerSimpleComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(
+            injectableTypeFile, componentSupertype, depComponentFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void wildcardGenericsRequiresAtProvides() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A() {}",
+        "}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "final class B<T> {",
+        "  @Inject B(T t) {}",
+        "}");
+    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "final class C {",
+        "  @Inject C(B<? extends A> bA) {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Lazy;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  C c();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(aFile, bFile, cFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "test.B<? extends test.A> cannot be provided without an @Provides-annotated method");
+  }
+  @Test
+  public void componentImplicitlyDependsOnGeneratedType() {
+    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SomeInjectableType {",
+        "  @Inject SomeInjectableType(GeneratedType generatedType) {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface SimpleComponent {",
+        "  SomeInjectableType someInjectableType();",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(injectableTypeFile, componentFile))
+        .processedWith(
+            new ComponentProcessor(),
+            new GeneratingProcessor(
+                "test.GeneratedType",
+                "package test;",
+                "",
+                "import javax.inject.Inject;",
+                "",
+                "final class GeneratedType {",
+                "  @Inject GeneratedType() {}",
+                "}"))
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(SOURCE_OUTPUT, "test", "DaggerSimpleComponent.java");
+  }
+  @Test
+  public void componentSupertypeDependsOnGeneratedType() {
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.SimpleComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component",
+            "interface SimpleComponent extends SimpleComponentInterface {}");
+    JavaFileObject interfaceFile =
+        JavaFileObjects.forSourceLines(
+            "test.SimpleComponentInterface",
+            "package test;",
+            "",
+            "interface SimpleComponentInterface {",
+            "  GeneratedType generatedType();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(componentFile, interfaceFile))
+        .processedWith(
+            new ComponentProcessor(),
+            new GeneratingProcessor(
+                "test.GeneratedType",
+                "package test;",
+                "",
+                "import javax.inject.Inject;",
+                "",
+                "final class GeneratedType {",
+                "  @Inject GeneratedType() {}",
+                "}"))
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(SOURCE_OUTPUT, "test", "DaggerSimpleComponent.java");
+  }
+
+  @Test
+  @Ignore // modify this test as necessary while debugging for your situation.
+  @SuppressWarnings("unused")
+  public void genericTestToLetMeDebugInEclipse() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+         "import javax.inject.Inject;",
+         "",
+         "public final class A {",
+         "  @Inject A() {}",
+         "}");
+     JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+         "package test;",
+         "",
+         "import javax.inject.Inject;",
+         "import javax.inject.Provider;",
+         "",
+         "public class B<T> {",
+         "  @Inject B() {}",
+         "}");
+     JavaFileObject dFile = JavaFileObjects.forSourceLines("test.sub.D",
+         "package test.sub;",
+         "",
+         "import javax.inject.Inject;",
+         "import javax.inject.Provider;",
+         "import test.B;",
+         "",
+         "public class D {",
+         "  @Inject D(B<A.InA> ba) {}",
+         "}");
+     JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
+         "package test;",
+         "",
+         "import dagger.Component;",
+         "import dagger.Lazy;",
+         "",
+         "import javax.inject.Provider;",
+         "",
+         "@Component",
+         "interface SimpleComponent {",
+         "  B<A> d();",
+         "  Provider<B<A>> d2();",
+         "}");
+     JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+         "test.DaggerSimpleComponent",
+         "package test;",
+         "",
+         "import javax.annotation.Generated;",
+         "import javax.inject.Provider;",
+         "",
+         "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+         "public final class DaggerSimpleComponent implements SimpleComponent {",
+         "  private Provider<D> dProvider;",
+         "",
+         "  private DaggerSimpleComponent(Builder builder) {",
+         "    assert builder != null;",
+         "    initialize(builder);",
+         "  }",
+         "",
+         "  public static Builder builder() {",
+         "    return new Builder();",
+         "  }",
+         "",
+         "  public static SimpleComponent create() {",
+         "    return builder().build();",
+         "  }",
+         "",
+         "  @SuppressWarnings(\"unchecked\")",
+         "  private void initialize(final Builder builder) {",
+         "    this.dProvider = new D_Factory(B_Factory.INSTANCE);",
+         "  }",
+         "",
+         "  @Override",
+         "  public D d() {",
+         "    return dProvider.get();",
+         "  }",
+         "",
+         "  public static final class Builder {",
+         "    private Builder() {",
+         "    }",
+         "",
+         "    public SimpleComponent build() {",
+         "      return new DaggerSimpleComponent(this);",
+         "    }",
+         "  }",
+         "}");
+     assertAbout(javaSources()).that(ImmutableList.of(aFile, bFile, componentFile))
+         .processedWith(new ComponentProcessor())
+         .compilesWithoutError()
+         .and().generatesSources(generatedComponent);
+   }
+
+  /**
+   * A simple {@link Processor} that generates one source file.
+   */
+  private static final class GeneratingProcessor extends AbstractProcessor {
+    private final String generatedClassName;
+    private final String generatedSource;
+    private boolean processed;
+
+    GeneratingProcessor(String generatedClassName, String... source) {
+      this.generatedClassName = generatedClassName;
+      this.generatedSource = Joiner.on("\n").join(source);
+    }
+
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+      return ImmutableSet.of("*");
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (!processed) {
+        processed = true;
+        try (Writer writer =
+                processingEnv.getFiler().createSourceFile(generatedClassName).openWriter()) {
+          writer.append(generatedSource);
+        } catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+      return false;
+    }
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java b/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java
new file mode 100644
index 0000000..b47a43c
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.Iterables;
+import com.google.testing.compile.CompilationRule;
+import dagger.Lazy;
+import dagger.MembersInjector;
+import dagger.Module;
+import dagger.Provides;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.util.List;
+import javax.inject.Provider;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+/**
+ * Test case for {@link DependencyRequestMapper}.
+ */
+@RunWith(JUnit4.class)
+public class DependencyRequestMapperTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  private Elements elements;
+  private Types types;
+  private Key.Factory keyFactory;
+  private DependencyRequest.Factory dependencyRequestFactory;
+
+  @Before public void setUp() {
+    this.types = compilationRule.getTypes();
+    this.elements = compilationRule.getElements();
+    this.keyFactory = new Key.Factory(types, elements);
+    this.dependencyRequestFactory = new DependencyRequest.Factory(elements, keyFactory);
+  }
+
+  private List<? extends VariableElement> sampleProviderParameters() {
+    TypeElement moduleElement =
+        elements.getTypeElement(ProvidesMethodModule.class.getCanonicalName());
+    ExecutableElement providesMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
+    return providesMethod.getParameters();
+  }
+
+  private List<? extends VariableElement> sampleProducerParameters() {
+    TypeElement moduleElement =
+        elements.getTypeElement(ProducesMethodModule.class.getCanonicalName());
+    ExecutableElement producesMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
+    return producesMethod.getParameters();
+  }
+
+  private DependencyRequest dependencyRequestForInstance() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(0));
+  }
+
+  private DependencyRequest dependencyRequestForLazy() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(1));
+  }
+
+  private DependencyRequest dependencyRequestForProvider() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(2));
+  }
+
+  private DependencyRequest dependencyRequestForMembersInjector() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(3));
+  }
+
+  private DependencyRequest dependencyRequestForProducer() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProducerParameters().get(0));
+  }
+
+  private DependencyRequest dependencyRequestForProduced() {
+    return dependencyRequestFactory.forRequiredVariable(sampleProducerParameters().get(1));
+  }
+
+  @Test public void forProvider() {
+    DependencyRequestMapper mapper = DependencyRequestMapper.FOR_PROVIDER;
+    assertThat(mapper.getFrameworkClass(dependencyRequestForInstance()))
+        .isEqualTo(Provider.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForLazy()))
+        .isEqualTo(Provider.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForProvider()))
+        .isEqualTo(Provider.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForMembersInjector()))
+        .isEqualTo(MembersInjector.class);
+  }
+
+  @Test public void forProducer() {
+    DependencyRequestMapper mapper = DependencyRequestMapper.FOR_PRODUCER;
+    assertThat(mapper.getFrameworkClass(dependencyRequestForInstance()))
+        .isEqualTo(Producer.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForLazy()))
+        .isEqualTo(Provider.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForProvider()))
+        .isEqualTo(Provider.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForMembersInjector()))
+        .isEqualTo(MembersInjector.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForProducer()))
+        .isEqualTo(Producer.class);
+    assertThat(mapper.getFrameworkClass(dependencyRequestForProduced()))
+        .isEqualTo(Producer.class);
+  }
+
+  @Module
+  static final class ProvidesMethodModule {
+    @Provides String provideString(
+        Integer a, Lazy<Integer> b, Provider<Integer> c, MembersInjector<Y> d) {
+      return null;
+    }
+  }
+
+  @ProducerModule
+  static final class ProducesMethodModule {
+    @Produces String produceString(Producer<Integer> a, Produced<Integer> b) {
+      return null;
+    }
+  }
+  
+  static final class Y {}
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ErrorMessagesTest.java b/compiler/src/test/java/dagger/internal/codegen/ErrorMessagesTest.java
new file mode 100644
index 0000000..141d5c4
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ErrorMessagesTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class ErrorMessagesTest {
+  @Test public void stripCommonTypePrefixes() {
+    String typeName = "com.google.common.collect.ImmutableList<java.lang.Boolean>";
+    assertThat(ErrorMessages.stripCommonTypePrefixes(typeName)).isEqualTo("ImmutableList<Boolean>");
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/GraphValidationScopingTest.java b/compiler/src/test/java/dagger/internal/codegen/GraphValidationScopingTest.java
new file mode 100644
index 0000000..e207fe0
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/GraphValidationScopingTest.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static java.util.Arrays.asList;
+
+@RunWith(JUnit4.class)
+public class GraphValidationScopingTest {
+  @Test public void componentWithoutScopeIncludesScopedBindings_Fail() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.MyComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Component(modules = ScopedModule.class)",
+        "interface MyComponent {",
+        "  ScopedType string();",
+        "}");
+    JavaFileObject typeFile = JavaFileObjects.forSourceLines("test.ScopedType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "class ScopedType {",
+        "  @Inject ScopedType(String s, long l, float f) {}",
+        "}");
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ScopedModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Module",
+        "class ScopedModule {",
+        "  @Provides @Singleton String string() { return \"a string\"; }",
+        "  @Provides long integer() { return 0L; }",
+        "  @Provides float floatingPoint() { return 0.0f; }",
+        "}");
+    String errorMessage = "test.MyComponent (unscoped) may not reference scoped bindings:\n"
+        + "      @Provides @Singleton String test.ScopedModule.string()\n"
+        + "      @Singleton class test.ScopedType";
+    assert_().about(javaSources()).that(asList(componentFile, typeFile, moduleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentWithScopeIncludesIncompatiblyScopedBindings_Fail() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.MyComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component(modules = ScopedModule.class)",
+        "interface MyComponent {",
+        "  ScopedType string();",
+        "}");
+    JavaFileObject scopeFile = JavaFileObjects.forSourceLines("test.PerTest",
+        "package test;",
+        "",
+        "import javax.inject.Scope;",
+        "",
+        "@Scope",
+        "@interface PerTest {}");
+    JavaFileObject typeFile = JavaFileObjects.forSourceLines("test.ScopedType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "@PerTest", // incompatible scope
+        "class ScopedType {",
+        "  @Inject ScopedType(String s, long l, float f) {}",
+        "}");
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ScopedModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Module",
+        "class ScopedModule {",
+        "  @Provides @PerTest String string() { return \"a string\"; }", // incompatible scope
+        "  @Provides long integer() { return 0L; }", // unscoped - valid
+        "  @Provides @Singleton float floatingPoint() { return 0.0f; }", // same scope - valid
+        "}");
+    String errorMessage = "test.MyComponent scoped with @Singleton "
+        + "may not reference bindings with different scopes:\n"
+        + "      @Provides @test.PerTest String test.ScopedModule.string()\n"
+        + "      @test.PerTest class test.ScopedType";
+    assert_().about(javaSources()).that(asList(componentFile, scopeFile, typeFile, moduleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentWithScopeMayDependOnOnlyOneScopedComponent() {
+    // If a scoped component will have dependencies, they must only include, at most, a single
+    // scoped component
+    JavaFileObject type = JavaFileObjects.forSourceLines("test.SimpleType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class SimpleType {",
+        "  @Inject SimpleType() {}",
+        "  static class A { @Inject A() {} }",
+        "  static class B { @Inject B() {} }",
+        "}");
+    JavaFileObject simpleScope = JavaFileObjects.forSourceLines("test.SimpleScope",
+        "package test;",
+        "",
+        "import javax.inject.Scope;",
+        "",
+        "@Scope @interface SimpleScope {}");
+    JavaFileObject singletonScopedA = JavaFileObjects.forSourceLines("test.SingletonComponentA",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component",
+        "interface SingletonComponentA {",
+        "  SimpleType.A type();",
+        "}");
+    JavaFileObject singletonScopedB = JavaFileObjects.forSourceLines("test.SingletonComponentB",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component",
+        "interface SingletonComponentB {",
+        "  SimpleType.B type();",
+        "}");
+    JavaFileObject scopeless = JavaFileObjects.forSourceLines("test.ScopelessComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface ScopelessComponent {",
+        "  SimpleType type();",
+        "}");
+    JavaFileObject simpleScoped = JavaFileObjects.forSourceLines("test.SimpleScopedComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@SimpleScope",
+        "@Component(dependencies = {SingletonComponentA.class, SingletonComponentB.class})",
+        "interface SimpleScopedComponent {",
+        "  SimpleType.A type();",
+        "}");
+    String errorMessage =
+        "@test.SimpleScope test.SimpleScopedComponent depends on more than one scoped component:\n"
+        + "      @Singleton test.SingletonComponentA\n"
+        + "      @Singleton test.SingletonComponentB";
+    assert_().about(javaSources())
+        .that(
+            asList(type, simpleScope, simpleScoped, singletonScopedA, singletonScopedB, scopeless))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentWithoutScopeCannotDependOnScopedComponent() {
+    JavaFileObject type = JavaFileObjects.forSourceLines("test.SimpleType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class SimpleType {",
+        "  @Inject SimpleType() {}",
+        "}");
+    JavaFileObject scopedComponent = JavaFileObjects.forSourceLines("test.ScopedComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component",
+        "interface ScopedComponent {",
+        "  SimpleType type();",
+        "}");
+    JavaFileObject unscopedComponent = JavaFileObjects.forSourceLines("test.UnscopedComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Component(dependencies = ScopedComponent.class)",
+        "interface UnscopedComponent {",
+        "  SimpleType type();",
+        "}");
+    String errorMessage =
+        "test.UnscopedComponent (unscoped) cannot depend on scoped components:\n"
+        + "      @Singleton test.ScopedComponent";
+    assert_().about(javaSources())
+        .that(asList(type, scopedComponent, unscopedComponent))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentWithSingletonScopeMayNotDependOnOtherScope() {
+    // Singleton must be the widest lifetime of present scopes.
+    JavaFileObject type = JavaFileObjects.forSourceLines("test.SimpleType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class SimpleType {",
+        "  @Inject SimpleType() {}",
+        "}");
+    JavaFileObject simpleScope = JavaFileObjects.forSourceLines("test.SimpleScope",
+        "package test;",
+        "",
+        "import javax.inject.Scope;",
+        "",
+        "@Scope @interface SimpleScope {}");
+    JavaFileObject simpleScoped = JavaFileObjects.forSourceLines("test.SimpleScopedComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@SimpleScope",
+        "@Component",
+        "interface SimpleScopedComponent {",
+        "  SimpleType type();",
+        "}");
+    JavaFileObject singletonScoped = JavaFileObjects.forSourceLines("test.SingletonComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Singleton",
+        "@Component(dependencies = SimpleScopedComponent.class)",
+        "interface SingletonComponent {",
+        "  SimpleType type();",
+        "}");
+    String errorMessage =
+        "This @Singleton component cannot depend on scoped components:\n"
+        + "      @test.SimpleScope test.SimpleScopedComponent";
+    assert_().about(javaSources())
+        .that(asList(type, simpleScope, simpleScoped, singletonScoped))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentScopeAncestryMustNotCycle() {
+    // The dependency relationship of components is necessarily from shorter lifetimes to
+    // longer lifetimes.  The scoping annotations must reflect this, and so one cannot declare
+    // scopes on components such that they cycle.
+    JavaFileObject type = JavaFileObjects.forSourceLines("test.SimpleType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class SimpleType {",
+        "  @Inject SimpleType() {}",
+        "}");
+    JavaFileObject scopeA = JavaFileObjects.forSourceLines("test.ScopeA",
+        "package test;",
+        "",
+        "import javax.inject.Scope;",
+        "",
+        "@Scope @interface ScopeA {}");
+    JavaFileObject scopeB = JavaFileObjects.forSourceLines("test.ScopeB",
+        "package test;",
+        "",
+        "import javax.inject.Scope;",
+        "",
+        "@Scope @interface ScopeB {}");
+    JavaFileObject longLifetime = JavaFileObjects.forSourceLines("test.ComponentLong",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@ScopeA",
+        "@Component",
+        "interface ComponentLong {",
+        "  SimpleType type();",
+        "}");
+    JavaFileObject mediumLifetime = JavaFileObjects.forSourceLines("test.ComponentMedium",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@ScopeB",
+        "@Component(dependencies = ComponentLong.class)",
+        "interface ComponentMedium {",
+        "  SimpleType type();",
+        "}");
+    JavaFileObject shortLifetime = JavaFileObjects.forSourceLines("test.ComponentShort",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@ScopeA",
+        "@Component(dependencies = ComponentMedium.class)",
+        "interface ComponentShort {",
+        "  SimpleType type();",
+        "}");
+    String errorMessage =
+        "test.ComponentShort depends on scoped components in a non-hierarchical scope ordering:\n"
+        + "      @test.ScopeA test.ComponentLong\n"
+        + "      @test.ScopeB test.ComponentMedium\n"
+        + "      @test.ScopeA test.ComponentShort";
+    assert_().about(javaSources())
+        .that(asList(type, scopeA, scopeB, longLifetime, mediumLifetime, shortLifetime))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/GraphValidationTest.java b/compiler/src/test/java/dagger/internal/codegen/GraphValidationTest.java
new file mode 100644
index 0000000..6001ea7
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/GraphValidationTest.java
@@ -0,0 +1,1143 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import java.util.Arrays;
+import javax.tools.JavaFileObject;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static dagger.internal.codegen.ErrorMessages.nullableToNonNullable;
+
+@RunWith(JUnit4.class)
+public class GraphValidationTest {
+  private final JavaFileObject NULLABLE = JavaFileObjects.forSourceLines("test.Nullable",
+      "package test;",
+      "public @interface Nullable {}");
+
+  @Test public void componentOnConcreteClass() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.MyComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface MyComponent {",
+        "  Foo getFoo();",
+        "}");
+    JavaFileObject injectable = JavaFileObjects.forSourceLines("test.Foo",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class Foo {",
+        "  @Inject Foo(Bar bar) {}",
+        "}");
+    JavaFileObject nonInjectable = JavaFileObjects.forSourceLines("test.Bar",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "interface Bar {}");
+    assertAbout(javaSources()).that(Arrays.asList(component, injectable, nonInjectable))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("test.Bar cannot be provided without an @Provides-annotated method.")
+            .in(component).onLine(7);
+  }
+
+  @Test public void componentProvisionWithNoDependencyChain() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.TestClass",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import javax.inject.Qualifier;",
+            "",
+            "final class TestClass {",
+            "  @Qualifier @interface Q {}",
+            "  interface A {}",
+            "",
+            "  @Component()",
+            "  interface AComponent {",
+            "    A getA();",
+            "    @Q A qualifiedA();",
+            "  }",
+            "}");
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "test.TestClass.A cannot be provided without an @Provides-annotated method.")
+        .in(component)
+        .onLine(12)
+        .and()
+        .withErrorContaining(
+            "@test.TestClass.Q test.TestClass.A "
+                + "cannot be provided without an @Provides-annotated method.")
+        .in(component)
+        .onLine(13);
+  }
+
+  @Test public void constructorInjectionWithoutAnnotation() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class TestClass {",
+        "  static class A {",
+        "    A() {}",
+        "  }",
+        "",
+        "  @Component()",
+        "  interface AComponent {",
+        "    A getA();",
+        "  }",
+        "}");
+    String expectedError = "test.TestClass.A cannot be provided without an "
+        + "@Inject constructor or from an @Provides-annotated method.";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(15);
+  }
+
+  @Test public void membersInjectWithoutProvision() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class TestClass {",
+        "  static class A {",
+        "    @Inject A() {}",
+        "  }",
+        "",
+        "  static class B {",
+        "    @Inject A a;",
+        "  }",
+        "",
+        "  @Component()",
+        "  interface AComponent {",
+        "    B getB();",
+        "  }",
+        "}");
+    String expectedError = "test.TestClass.B cannot be provided without an "
+        + "@Inject constructor or from an @Provides-annotated method. "
+        + "This type supports members injection but cannot be implicitly provided.";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(19);
+  }
+
+  @Test public void cyclicDependency() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class Outer {",
+        "  static class A {",
+        "    @Inject A(C cParam) {}",
+        "  }",
+        "",
+        "  static class B {",
+        "    @Inject B(A aParam) {}",
+        "  }",
+        "",
+        "  static class C {",
+        "    @Inject C(B bParam) {}",
+        "  }",
+        "",
+        "  @Component()",
+        "  interface CComponent {",
+        "    C getC();",
+        "  }",
+        "}");
+
+    String expectedError = "test.Outer.CComponent.getC() contains a dependency cycle:\n"
+        + "      test.Outer.C.<init>(test.Outer.B bParam)\n"
+        + "          [parameter: test.Outer.B bParam]\n"
+        + "      test.Outer.B.<init>(test.Outer.A aParam)\n"
+        + "          [parameter: test.Outer.A aParam]\n"
+        + "      test.Outer.A.<init>(test.Outer.C cParam)\n"
+        + "          [parameter: test.Outer.C cParam]";
+
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(23);
+  }
+
+  @Test public void cyclicDependencyNotIncludingEntryPoint() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.Outer",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import javax.inject.Inject;",
+            "",
+            "final class Outer {",
+            "  static class A {",
+            "    @Inject A(C cParam) {}",
+            "  }",
+            "",
+            "  static class B {",
+            "    @Inject B(A aParam) {}",
+            "  }",
+            "",
+            "  static class C {",
+            "    @Inject C(B bParam) {}",
+            "  }",
+            "",
+            "  static class D {",
+            "    @Inject D(C cParam) {}",
+            "  }",
+            "",
+            "  @Component()",
+            "  interface DComponent {",
+            "    D getD();",
+            "  }",
+            "}");
+
+    String expectedError = "test.Outer.DComponent.getD() contains a dependency cycle:\n"
+        + "      test.Outer.D.<init>(test.Outer.C cParam)\n"
+        + "          [parameter: test.Outer.C cParam]\n"
+        + "      test.Outer.C.<init>(test.Outer.B bParam)\n"
+        + "          [parameter: test.Outer.B bParam]\n"
+        + "      test.Outer.B.<init>(test.Outer.A aParam)\n"
+        + "          [parameter: test.Outer.A aParam]\n"
+        + "      test.Outer.A.<init>(test.Outer.C cParam)\n"
+        + "          [parameter: test.Outer.C cParam]";
+
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError)
+        .in(component)
+        .onLine(27);
+  }
+
+  @Test
+  public void cyclicDependencyNotBrokenByMapBinding() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.Outer",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import dagger.MapKey;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import java.util.Map;",
+            "import javax.inject.Inject;",
+            "",
+            "final class Outer {",
+            "  static class A {",
+            "    @Inject A(Map<String, C> cMap) {}",
+            "  }",
+            "",
+            "  static class B {",
+            "    @Inject B(A aParam) {}",
+            "  }",
+            "",
+            "  static class C {",
+            "    @Inject C(B bParam) {}",
+            "  }",
+            "",
+            "  @Component(modules = CModule.class)",
+            "  interface CComponent {",
+            "    C getC();",
+            "  }",
+            "",
+            "  @Module",
+            "  static class CModule {",
+            "    @Provides(type = Provides.Type.MAP)",
+            "    @StringKey(\"C\")",
+            "    static C c(C c) {",
+            "      return c;",
+            "    }",
+            "  }",
+            "",
+            "  @MapKey",
+            "  @interface StringKey {",
+            "    String value();",
+            "  }",
+            "}");
+
+    String expectedError =
+        Joiner.on('\n')
+            .join(
+                "test.Outer.CComponent.getC() contains a dependency cycle:",
+                "      test.Outer.C.<init>(test.Outer.B bParam)",
+                "          [parameter: test.Outer.B bParam]",
+                "      test.Outer.B.<init>(test.Outer.A aParam)",
+                "          [parameter: test.Outer.A aParam]",
+                "      test.Outer.A.<init>(java.util.Map<java.lang.String,test.Outer.C> cMap)",
+                "          [parameter: java.util.Map<java.lang.String,test.Outer.C> cMap]",
+                "      test.Outer.A.<init>(java.util.Map<java.lang.String,test.Outer.C> cMap)",
+                "          [parameter: java.util.Map<java.lang.String,test.Outer.C> cMap]",
+                "      test.Outer.CModule.c(test.Outer.C c)",
+                "          [parameter: test.Outer.C c]");
+
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError)
+        .in(component)
+        .onLine(25);
+  }
+
+  @Test
+  public void falsePositiveCyclicDependencyIndirectionDetected() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.Outer",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import javax.inject.Inject;",
+            "import javax.inject.Provider;",
+            "",
+            "final class Outer {",
+            "  static class A {",
+            "    @Inject A(C cParam) {}",
+            "  }",
+            "",
+            "  static class B {",
+            "    @Inject B(A aParam) {}",
+            "  }",
+            "",
+            "  static class C {",
+            "    @Inject C(B bParam) {}",
+            "  }",
+            "",
+            "  static class D {",
+            "    @Inject D(Provider<C> cParam) {}",
+            "  }",
+            "",
+            "  @Component()",
+            "  interface DComponent {",
+            "    D getD();",
+            "  }",
+            "}");
+
+    String expectedError =
+        "test.Outer.DComponent.getD() contains a dependency cycle:\n"
+            + "      test.Outer.D.<init>(javax.inject.Provider<test.Outer.C> cParam)\n"
+            + "          [parameter: javax.inject.Provider<test.Outer.C> cParam]\n"
+            + "      test.Outer.C.<init>(test.Outer.B bParam)\n"
+            + "          [parameter: test.Outer.B bParam]\n"
+            + "      test.Outer.B.<init>(test.Outer.A aParam)\n"
+            + "          [parameter: test.Outer.A aParam]\n"
+            + "      test.Outer.A.<init>(test.Outer.C cParam)\n"
+            + "          [parameter: test.Outer.C cParam]";
+
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError)
+        .in(component)
+        .onLine(28);
+  }
+
+  @Ignore @Test public void cyclicDependencySimpleProviderIndirectionWarning() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.Outer",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import javax.inject.Inject;",
+            "import javax.inject.Provider;",
+            "",
+            "final class Outer {",
+            "  static class A {",
+            "    @Inject A(B bParam) {}",
+            "  }",
+            "",
+            "  static class B {",
+            "    @Inject B(C bParam, D dParam) {}",
+            "  }",
+            "",
+            "  static class C {",
+            "    @Inject C(Provider<A> aParam) {}",
+            "  }",
+            "",
+            "  static class D {",
+            "    @Inject D() {}",
+            "  }",
+            "",
+            "  @Component()",
+            "  interface CComponent {",
+            "    C get();",
+            "  }",
+            "}");
+
+    /* String expectedWarning =
+     "test.Outer.CComponent.get() contains a dependency cycle:"
+     + "      test.Outer.C.<init>(javax.inject.Provider<test.Outer.A> aParam)"
+     + "          [parameter: javax.inject.Provider<test.Outer.A> aParam]"
+     + "      test.Outer.A.<init>(test.Outer.B bParam)"
+     + "          [parameter: test.Outer.B bParam]"
+     + "      test.Outer.B.<init>(test.Outer.C bParam, test.Outer.D dParam)"
+     + "          [parameter: test.Outer.C bParam]";
+     */
+    assertAbout(javaSource()) // TODO(cgruber): Implement warning checks.
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+        //.withWarningContaining(expectedWarning).in(component).onLine(X);
+  }
+
+  @Ignore @Test public void cyclicDependencySimpleProviderIndirectionWarningSuppressed() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.Outer",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import javax.inject.Inject;",
+            "import javax.inject.Provider;",
+            "",
+            "final class Outer {",
+            "  static class A {",
+            "    @Inject A(B bParam) {}",
+            "  }",
+            "",
+            "  static class B {",
+            "    @Inject B(C bParam, D dParam) {}",
+            "  }",
+            "",
+            "  static class C {",
+            "    @Inject C(Provider<A> aParam) {}",
+            "  }",
+            "",
+            "  static class D {",
+            "    @Inject D() {}",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"dependency-cycle\")",
+            "  @Component()",
+            "  interface CComponent {",
+            "    C get();",
+            "  }",
+            "}");
+
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+        //.compilesWithoutWarning(); //TODO(cgruber)
+  }
+  
+  @Test public void duplicateExplicitBindings_ProvidesAndComponentProvision() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "final class Outer {",
+        "  interface A {}",
+        "",
+        "  interface B {}",
+        "",
+        "  @Module",
+        "  static class AModule {",
+        "    @Provides String provideString() { return \"\"; }",
+        "    @Provides A provideA(String s) { return new A() {}; }",
+        "  }",
+        "",
+        "  @Component(modules = AModule.class)",
+        "  interface Parent {",
+        "    A getA();",
+        "  }",
+        "",
+        "  @Module",
+        "  static class BModule {",
+        "    @Provides B provideB(A a) { return new B() {}; }",
+        "  }",
+        "",
+        "  @Component(dependencies = Parent.class, modules = { BModule.class, AModule.class})",
+        "  interface Child {",
+        "    B getB();",
+        "  }",
+        "}");
+
+    String expectedError = "test.Outer.A is bound multiple times:\n"
+        + "      test.Outer.A test.Outer.Parent.getA()\n"
+        + "      @Provides test.Outer.A test.Outer.AModule.provideA(String)";
+
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(30);
+  }
+
+  @Test public void duplicateExplicitBindings_TwoProvidesMethods() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class Outer {",
+        "  interface A {}",
+        "",
+        "  @Module",
+        "  static class Module1 {",
+        "    @Provides A provideA1() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module2 {",
+        "    @Provides String provideString() { return \"\"; }",
+        "    @Provides A provideA2(String s) { return new A() {}; }",
+        "  }",
+        "",
+        "  @Component(modules = { Module1.class, Module2.class})",
+        "  interface TestComponent {",
+        "    A getA();",
+        "  }",
+        "}");
+
+    String expectedError = "test.Outer.A is bound multiple times:\n"
+        + "      @Provides test.Outer.A test.Outer.Module1.provideA1()\n"
+        + "      @Provides test.Outer.A test.Outer.Module2.provideA2(String)";
+
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(24);
+  }
+  
+  @Test public void duplicateExplicitBindings_MultipleProvisionTypes() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.MapKey;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import dagger.MapKey;",
+        "import java.util.HashMap;",
+        "import java.util.HashSet;",
+        "import java.util.Map;",
+        "import java.util.Set;",
+        "",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "import static dagger.Provides.Type.MAP;",
+        "import static dagger.Provides.Type.SET;",
+        "",
+        "final class Outer {",
+        "  @MapKey(unwrapValue = true)",
+        "  @interface StringKey {",
+        "    String value();",
+        "  }",
+        "",
+        "  @Module",
+        "  static class TestModule1 {",
+        "    @Provides(type = MAP)",
+        "    @StringKey(\"foo\")",
+        "    String stringMapEntry() { return \"\"; }",
+        "",
+        "    @Provides(type = SET) String stringSetElement() { return \"\"; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class TestModule2 {",
+        "    @Provides Set<String> stringSet() { return new HashSet<String>(); }",
+        "",
+        "    @Provides Map<String, String> stringMap() {",
+        "      return new HashMap<String, String>();",
+        "    }",
+        "  }",
+        "",
+        "  @Component(modules = { TestModule1.class, TestModule2.class })",
+        "  interface TestComponent {",
+        "    Set<String> getStringSet();",
+        "    Map<String, String> getStringMap();",
+        "  }",
+        "}");
+
+    String expectedSetError =
+        "java.util.Set<java.lang.String> has incompatible bindings:\n"
+            + "      Set bindings:\n"
+            + "          @Provides(type=SET) String test.Outer.TestModule1.stringSetElement()\n"
+            + "      Unique bindings:\n"
+            + "          @Provides Set<String> test.Outer.TestModule2.stringSet()";
+
+    String expectedMapError =
+        "java.util.Map<java.lang.String,java.lang.String> has incompatible bindings:\n"
+            + "      Map bindings:\n"
+            + "          @Provides(type=MAP) @test.Outer.StringKey(\"foo\") String"
+            + " test.Outer.TestModule1.stringMapEntry()\n"
+            + "      Unique bindings:\n"
+            + "          @Provides Map<String,String> test.Outer.TestModule2.stringMap()";
+
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedSetError).in(component).onLine(43)
+        .and().withErrorContaining(expectedMapError).in(component).onLine(44);
+  }
+  
+  @Test public void duplicateBindings_TruncateAfterLimit() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class Outer {",
+        "  interface A {}",
+        "",
+        "  @Module",
+        "  static class Module1 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module2 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module3 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module4 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module5 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module6 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module7 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module8 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module9 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module10 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module11 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Module",
+        "  static class Module12 {",
+        "    @Provides A provideA() { return new A() {}; }",
+        "  }",
+        "",
+        "  @Component(modules = {",
+        "    Module1.class,",
+        "    Module2.class,",
+        "    Module3.class,",
+        "    Module4.class,",
+        "    Module5.class,",
+        "    Module6.class,",
+        "    Module7.class,",
+        "    Module8.class,",
+        "    Module9.class,",
+        "    Module10.class,",
+        "    Module11.class,",
+        "    Module12.class",
+        "  })",
+        "  interface TestComponent {",
+        "    A getA();",
+        "  }",
+        "}");
+
+    String expectedError = "test.Outer.A is bound multiple times:\n"
+        + "      @Provides test.Outer.A test.Outer.Module1.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module2.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module3.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module4.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module5.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module6.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module7.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module8.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module9.provideA()\n"
+        + "      @Provides test.Outer.A test.Outer.Module10.provideA()\n"
+        + "      and 2 others";
+
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(86);
+  }
+
+  @Test public void longChainOfDependencies() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "final class TestClass {",
+        "  interface A {}",
+        "",
+        "  static class B {",
+        "    @Inject B(A a) {}",
+        "  }",
+        "",
+        "  static class C {",
+        "    @Inject B b;",
+        "    @Inject C(B b) {}",
+        "  }",
+        "",
+        "  interface D { }",
+        "",
+        "  static class DImpl implements D {",
+        "    @Inject DImpl(C c, B b) {}",
+        "  }",
+        "",
+        "  @Module",
+        "  static class DModule {",
+        "    @Provides D d(DImpl impl) { return impl; }",
+        "  }",
+        "",
+        "  @Component(modules = { DModule.class })",
+        "  interface AComponent {",
+        "    D getFoo();",
+        "    C injectC(C c);",
+        "  }",
+        "}");
+    String errorText =
+        "test.TestClass.A cannot be provided without an @Provides-annotated method.\n";
+    String firstError = errorText
+        + "      test.TestClass.DModule.d(test.TestClass.DImpl impl)\n"
+        + "          [parameter: test.TestClass.DImpl impl]\n"
+        + "      test.TestClass.DImpl.<init>(test.TestClass.C c, test.TestClass.B b)\n"
+        + "          [parameter: test.TestClass.C c]\n"
+        + "      test.TestClass.C.b\n"
+        + "          [injected field of type: test.TestClass.B b]\n"
+        + "      test.TestClass.B.<init>(test.TestClass.A a)\n"
+        + "          [parameter: test.TestClass.A a]";
+    String secondError = errorText
+        + "      test.TestClass.C.b\n"
+        + "          [injected field of type: test.TestClass.B b]\n"
+        + "      test.TestClass.B.<init>(test.TestClass.A a)\n"
+        + "          [parameter: test.TestClass.A a]";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(firstError).in(component).onLine(33)
+        .and().withErrorContaining(secondError).in(component).onLine(34);
+  }
+
+  @Test public void resolvedParametersInDependencyTrace() {
+    JavaFileObject generic = JavaFileObjects.forSourceLines("test.Generic",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "final class Generic<T> {",
+        "  @Inject Generic(T t) {}",
+        "}");
+    JavaFileObject testClass = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import java.util.List;",
+        "",
+        "final class TestClass {",
+        "  @Inject TestClass(List list) {}",
+        "}");
+    JavaFileObject usesTest = JavaFileObjects.forSourceLines("test.UsesTest",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class UsesTest {",
+        "  @Inject UsesTest(Generic<TestClass> genericTestClass) {}",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  UsesTest usesTest();",
+        "}");
+    String expectedMsg = Joiner.on("\n").join(
+        "java.util.List cannot be provided without an @Provides-annotated method.",
+        "      test.UsesTest.<init>(test.Generic<test.TestClass> genericTestClass)",
+        "          [parameter: test.Generic<test.TestClass> genericTestClass]",
+        "      test.Generic.<init>(test.TestClass t)",
+        "          [parameter: test.TestClass t]",
+        "      test.TestClass.<init>(java.util.List list)",
+        "          [parameter: java.util.List list]");
+    assertAbout(javaSources()).that(ImmutableList.of(generic, testClass, usesTest, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedMsg);
+  }
+
+  @Test public void resolvedVariablesInDependencyTrace() {
+    JavaFileObject generic = JavaFileObjects.forSourceLines("test.Generic",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "final class Generic<T> {",
+        "  @Inject T t;",
+        "  @Inject Generic() {}",
+        "}");
+    JavaFileObject testClass = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import java.util.List;",
+        "",
+        "final class TestClass {",
+        "  @Inject TestClass(List list) {}",
+        "}");
+    JavaFileObject usesTest = JavaFileObjects.forSourceLines("test.UsesTest",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class UsesTest {",
+        "  @Inject UsesTest(Generic<TestClass> genericTestClass) {}",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  UsesTest usesTest();",
+        "}");
+    String expectedMsg = Joiner.on("\n").join(
+        "java.util.List cannot be provided without an @Provides-annotated method.",
+        "      test.UsesTest.<init>(test.Generic<test.TestClass> genericTestClass)",
+        "          [parameter: test.Generic<test.TestClass> genericTestClass]",
+        "      test.Generic.t",
+        "          [injected field of type: test.TestClass t]",
+        "      test.TestClass.<init>(java.util.List list)",
+        "          [parameter: java.util.List list]");
+    assertAbout(javaSources()).that(ImmutableList.of(generic, testClass, usesTest, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedMsg);
+  }
+
+  @Test public void nullCheckForConstructorParameters() {
+    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A(String string) {}",
+        "}");
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class TestModule {",
+        "  @Nullable @Provides String provideString() { return null; }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  A a();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            nullableToNonNullable(
+                "java.lang.String",
+                "@test.Nullable @Provides String test.TestModule.provideString()"));
+
+    // but if we disable the validation, then it compiles fine.
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void nullCheckForMembersInjectParam() {
+    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A() {}",
+        "  @Inject void register(String string) {}",
+        "}");
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class TestModule {",
+        "  @Nullable @Provides String provideString() { return null; }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  A a();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            nullableToNonNullable(
+                "java.lang.String",
+                "@test.Nullable @Provides String test.TestModule.provideString()"));
+
+    // but if we disable the validation, then it compiles fine.
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void nullCheckForVariable() {
+    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject String string;",
+        "  @Inject A() {}",
+        "}");
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class TestModule {",
+        "  @Nullable @Provides String provideString() { return null; }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  A a();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            nullableToNonNullable(
+                "java.lang.String",
+                "@test.Nullable @Provides String test.TestModule.provideString()"));
+
+    // but if we disable the validation, then it compiles fine.
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, a, module, component))
+        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void nullCheckForComponentReturn() {
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class TestModule {",
+        "  @Nullable @Provides String provideString() { return null; }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(modules = TestModule.class)",
+        "interface TestComponent {",
+        "  String string();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, module, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            nullableToNonNullable(
+                "java.lang.String",
+                "@test.Nullable @Provides String test.TestModule.provideString()"));
+
+    // but if we disable the validation, then it compiles fine.
+    assertAbout(javaSources()).that(ImmutableList.of(NULLABLE, module, component))
+        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void componentDependencyMustNotCycle_Direct() {
+    JavaFileObject shortLifetime = JavaFileObjects.forSourceLines("test.ComponentShort",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(dependencies = ComponentShort.class)",
+        "interface ComponentShort {",
+        "}");
+    String errorMessage =
+        "test.ComponentShort contains a cycle in its component dependencies:\n"
+            + "      test.ComponentShort";
+    assertAbout(javaSource())
+        .that(shortLifetime)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage);
+  }
+
+  @Test public void componentDependencyMustNotCycle_Indirect() {
+    JavaFileObject longLifetime = JavaFileObjects.forSourceLines("test.ComponentLong",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(dependencies = ComponentMedium.class)",
+        "interface ComponentLong {",
+        "}");
+    JavaFileObject mediumLifetime = JavaFileObjects.forSourceLines("test.ComponentMedium",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(dependencies = ComponentLong.class)",
+        "interface ComponentMedium {",
+        "}");
+    JavaFileObject shortLifetime = JavaFileObjects.forSourceLines("test.ComponentShort",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component(dependencies = ComponentMedium.class)",
+        "interface ComponentShort {",
+        "}");
+    String longErrorMessage =
+        "test.ComponentLong contains a cycle in its component dependencies:\n"
+            + "      test.ComponentLong\n"
+            + "      test.ComponentMedium\n"
+            + "      test.ComponentLong";
+    String mediumErrorMessage =
+        "test.ComponentMedium contains a cycle in its component dependencies:\n"
+            + "      test.ComponentMedium\n"
+            + "      test.ComponentLong\n"
+            + "      test.ComponentMedium";
+    String shortErrorMessage =
+        "test.ComponentShort contains a cycle in its component dependencies:\n"
+            + "      test.ComponentMedium\n"
+            + "      test.ComponentLong\n"
+            + "      test.ComponentMedium\n"
+            + "      test.ComponentShort";
+    assertAbout(javaSources())
+        .that(ImmutableList.of(longLifetime, mediumLifetime, shortLifetime))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(longErrorMessage).in(longLifetime)
+        .and()
+        .withErrorContaining(mediumErrorMessage).in(mediumLifetime)
+        .and()
+        .withErrorContaining(shortErrorMessage).in(shortLifetime);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/InaccessibleTypeTest.java b/compiler/src/test/java/dagger/internal/codegen/InaccessibleTypeTest.java
new file mode 100644
index 0000000..6355922
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/InaccessibleTypeTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class InaccessibleTypeTest {
+  @Test public void basicInjectedType() {
+    JavaFileObject noDepClassFile = JavaFileObjects.forSourceLines("foreign.NoDepClass",
+        "package foreign;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public final class NoDepClass {",
+        "  @Inject NoDepClass() {}",
+        "}");
+    JavaFileObject publicClassFile = JavaFileObjects.forSourceLines("foreign.PublicClass",
+        "package foreign;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public final class PublicClass {",
+        "  @Inject PublicClass(NonPublicClass1 dep1, NonPublicClass2 dep2, NoDepClass dep3) {}",
+        "}");
+    JavaFileObject nonPublicClass1File = JavaFileObjects.forSourceLines("foreign.NonPublicClass1",
+        "package foreign;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class NonPublicClass1 {",
+        "  @Inject NonPublicClass1(NoDepClass dep) {}",
+        "}");
+    JavaFileObject nonPublicClass2File = JavaFileObjects.forSourceLines("foreign.NonPublicClass2",
+        "package foreign;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class NonPublicClass2 {",
+        "  @Inject NonPublicClass2(NoDepClass dep) {}",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import foreign.PublicClass;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  PublicClass publicClass();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import foreign.NoDepClass_Factory;",
+        "import foreign.NonPublicClass1_Factory;",
+        "import foreign.NonPublicClass2_Factory;",
+        "import foreign.PublicClass;",
+        "import foreign.PublicClass_Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  @SuppressWarnings(\"rawtypes\")",
+        "  private Provider nonPublicClass1Provider;",
+        "  @SuppressWarnings(\"rawtypes\")",
+        "  private Provider nonPublicClass2Provider;",
+        "  private Provider<PublicClass> publicClassProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.nonPublicClass1Provider =",
+        "        NonPublicClass1_Factory.create(NoDepClass_Factory.create());",
+        "    this.nonPublicClass2Provider =",
+        "        NonPublicClass2_Factory.create(NoDepClass_Factory.create());",
+        "    this.publicClassProvider = PublicClass_Factory.create(",
+        "        nonPublicClass1Provider,",
+        "        nonPublicClass2Provider,",
+        "        NoDepClass_Factory.create());",
+        "  }",
+        "",
+        "  @Override",
+        "  public PublicClass publicClass() {",
+        "    return publicClassProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            noDepClassFile,
+            publicClassFile,
+            nonPublicClass1File,
+            nonPublicClass2File,
+            componentFile))
+        .withCompilerOptions("-Xlint:rawtypes", "-Xlint:unchecked", "-Werror")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test public void memberInjectedType() {
+    JavaFileObject noDepClassFile = JavaFileObjects.forSourceLines("test.NoDepClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public final class NoDepClass {",
+        "  @Inject NoDepClass() {}",
+        "}");
+    JavaFileObject aClassFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import foreign.B;",
+        "import javax.inject.Inject;",
+        "",
+        "final class A extends B {",
+        "  @Inject NoDepClass dep;",
+        "}");
+    JavaFileObject bClassFile = JavaFileObjects.forSourceLines("foreign.B",
+        "package foreign;",
+        "",
+        "import test.NoDepClass;",
+        "import javax.inject.Inject;",
+        "",
+        "public class B extends C {",
+        "  @Inject NoDepClass dep;",
+        "}");
+    JavaFileObject cClassFile = JavaFileObjects.forSourceLines("foreign.C",
+        "package foreign;",
+        "",
+        "import test.D;",
+        "import test.NoDepClass;",
+        "import javax.inject.Inject;",
+        "",
+        "class C extends D {",
+        "  @Inject NoDepClass dep;",
+        "}");
+    JavaFileObject dClassFile = JavaFileObjects.forSourceLines("test.D",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public class D {",
+        "  @Inject NoDepClass dep;",
+        "}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  void injectA(A a);",
+        "}");
+    JavaFileObject generatedComponent =
+        JavaFileObjects.forSourceLines(
+            "test.DaggerTestComponent",
+            "package test;",
+            "",
+            "import dagger.MembersInjector;",
+            "import javax.annotation.Generated;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class DaggerTestComponent implements TestComponent {",
+            "  private MembersInjector<A> aMembersInjector;",
+            "",
+            "  private DaggerTestComponent(Builder builder) {",
+            "    assert builder != null;",
+            "    initialize(builder);",
+            "  }",
+            "",
+            "  public static Builder builder() {",
+            "    return new Builder();",
+            "  }",
+            "",
+            "  public static TestComponent create() {",
+            "    return builder().build();",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\")",
+            "  private void initialize(final Builder builder) {",
+            "     this.aMembersInjector = A_MembersInjector.create(NoDepClass_Factory.create());",
+            "  }",
+            "",
+            "  @Override",
+            "  public void injectA(A a) {",
+            "    aMembersInjector.injectMembers(a);",
+            "  }",
+            "",
+            "  public static final class Builder {",
+            "    private Builder() {",
+            "    }",
+            "",
+            "    public TestComponent build() {",
+            "      return new DaggerTestComponent(this);",
+            "    }",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            noDepClassFile,
+            aClassFile,
+            bClassFile,
+            cClassFile,
+            dClassFile,
+            componentFile))
+        .withCompilerOptions("-Xlint:rawtypes", "-Xlint:unchecked", "-Werror")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java b/compiler/src/test/java/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java
new file mode 100644
index 0000000..ca0494e
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java
@@ -0,0 +1,1128 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static dagger.internal.codegen.ErrorMessages.ABSTRACT_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.FINAL_INJECT_FIELD;
+import static dagger.internal.codegen.ErrorMessages.GENERIC_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.INJECT_CONSTRUCTOR_ON_ABSTRACT_CLASS;
+import static dagger.internal.codegen.ErrorMessages.INJECT_CONSTRUCTOR_ON_INNER_CLASS;
+import static dagger.internal.codegen.ErrorMessages.INJECT_ON_PRIVATE_CONSTRUCTOR;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_INJECT_CONSTRUCTORS;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_QUALIFIERS;
+import static dagger.internal.codegen.ErrorMessages.MULTIPLE_SCOPES;
+import static dagger.internal.codegen.ErrorMessages.PRIVATE_INJECT_FIELD;
+import static dagger.internal.codegen.ErrorMessages.PRIVATE_INJECT_METHOD;
+import static dagger.internal.codegen.ErrorMessages.QUALIFIER_ON_INJECT_CONSTRUCTOR;
+import static dagger.internal.codegen.ErrorMessages.STATIC_INJECT_FIELD;
+import static dagger.internal.codegen.ErrorMessages.STATIC_INJECT_METHOD;
+
+@RunWith(JUnit4.class)
+// TODO(gak): add tests for generation in the default package.
+public final class InjectConstructorFactoryGeneratorTest {
+  private static final JavaFileObject QUALIFIER_A =
+      JavaFileObjects.forSourceLines("test.QualifierA",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierA {}");
+  private static final JavaFileObject QUALIFIER_B =
+      JavaFileObjects.forSourceLines("test.QualifierB",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierB {}");
+  private static final JavaFileObject SCOPE_A =
+      JavaFileObjects.forSourceLines("test.ScopeA",
+          "package test;",
+          "",
+          "import javax.inject.Scope;",
+          "",
+          "@Scope @interface ScopeA {}");
+  private static final JavaFileObject SCOPE_B =
+      JavaFileObjects.forSourceLines("test.ScopeB",
+          "package test;",
+          "",
+          "import javax.inject.Scope;",
+          "",
+          "@Scope @interface ScopeB {}");
+
+  @Test public void injectOnPrivateConstructor() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateConstructor",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class PrivateConstructor {",
+        "  @Inject private PrivateConstructor() {}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(INJECT_ON_PRIVATE_CONSTRUCTOR).in(file).onLine(6);
+  }
+
+  @Test public void injectConstructorOnInnerClass() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class OuterClass {",
+        "  class InnerClass {",
+        "    @Inject InnerClass() {}",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(INJECT_CONSTRUCTOR_ON_INNER_CLASS).in(file).onLine(7);
+  }
+
+  @Test public void injectConstructorOnAbstractClass() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "abstract class AbstractClass {",
+        "  @Inject AbstractClass() {}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(INJECT_CONSTRUCTOR_ON_ABSTRACT_CLASS).in(file).onLine(6);
+  }
+
+  @Test public void injectConstructorOnGenericClass() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class GenericClass<T> {",
+        "  @Inject GenericClass(T t) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> {",
+        "  private final Provider<T> tProvider;",
+        "",
+        "  public GenericClass_Factory(Provider<T> tProvider) {",
+        "    assert tProvider != null;",
+        "    this.tProvider = tProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public GenericClass<T> get() {",
+        "    return new GenericClass<T>(tProvider.get());",
+        "  }",
+        "",
+        "  public static <T> Factory<GenericClass<T>> create(Provider<T> tProvider) {",
+        "    return new GenericClass_Factory<T>(tProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void fieldAndMethodGenerics() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class GenericClass<A, B> {",
+        "  @Inject A a;",
+        "",
+        "  @Inject GenericClass() {}",
+        "",
+        " @Inject void register(B b) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> {",
+        "  private final MembersInjector<GenericClass<A, B>> membersInjector;",
+        "",
+        "  public GenericClass_Factory(MembersInjector<GenericClass<A, B>> membersInjector) {",
+        "    assert membersInjector != null;",
+        "    this.membersInjector = membersInjector;",
+        "  }",
+        "",
+        "  @Override",
+        "  public GenericClass<A, B> get() {",
+        "    GenericClass<A, B> instance = new GenericClass<A, B>();",
+        "    membersInjector.injectMembers(instance);",
+        "    return instance;",
+        "  }",
+        "",
+        "  public static <A, B> Factory<GenericClass<A, B>> create(",
+        "      MembersInjector<GenericClass<A, B>> membersInjector) {",
+        "    return new GenericClass_Factory<A, B>(membersInjector);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void genericClassWithNoDependencies() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class GenericClass<T> {",
+        "  @Inject GenericClass() {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@SuppressWarnings(\"rawtypes\")",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public enum GenericClass_Factory implements Factory<GenericClass> {",
+        "  INSTANCE;",
+        "",
+        "  @Override",
+        "  public GenericClass get() {",
+        "    return new GenericClass();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  public static <T> Factory<GenericClass<T>> create() {",
+        "    return (Factory) INSTANCE;",
+        "  }",
+        "",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void twoGenericTypes() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class GenericClass<A, B> {",
+        "  @Inject GenericClass(A a, B b) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> {",
+        "  private final Provider<A> aProvider;",
+        "  private final Provider<B> bProvider;",
+        "",
+        "  public GenericClass_Factory(Provider<A> aProvider, Provider<B> bProvider) {",
+        "    assert aProvider != null;",
+        "    this.aProvider = aProvider;",
+        "    assert bProvider != null;",
+        "    this.bProvider = bProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public GenericClass<A, B> get() {",
+        "    return new GenericClass<A, B>(aProvider.get(), bProvider.get());",
+        "  }",
+        "",
+        "  public static <A, B> Factory<GenericClass<A, B>> create(",
+        "      Provider<A> aProvider, Provider<B> bProvider) {",
+        "    return new GenericClass_Factory<A, B>(aProvider, bProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+  
+  @Test public void boundedGenerics() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import java.util.List;",
+        "",
+        "class GenericClass<A extends Number & Comparable<A>,",
+        "    B extends List<? extends String>,",
+        "    C extends List<? super String>> {",
+        "  @Inject GenericClass(A a, B b, C c) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.List;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_Factory<A extends Number & Comparable<A>,",
+        "        B extends List<? extends String>,",
+        "        C extends List<? super String>>",
+        "    implements Factory<GenericClass<A, B, C>> {",
+        "  private final Provider<A> aProvider;",
+        "  private final Provider<B> bProvider;",
+        "  private final Provider<C> cProvider;",
+        "",
+        "  public GenericClass_Factory(Provider<A> aProvider,",
+        "      Provider<B> bProvider,",
+        "      Provider<C> cProvider) {",
+        "    assert aProvider != null;",
+        "    this.aProvider = aProvider;",
+        "    assert bProvider != null;",
+        "    this.bProvider = bProvider;",
+        "    assert cProvider != null;",
+        "    this.cProvider = cProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public GenericClass<A, B, C> get() {",
+        "    return new GenericClass<A, B, C>(aProvider.get(), bProvider.get(), cProvider.get());",
+        "  }",
+        "",
+        "  public static <A extends Number & Comparable<A>,",
+        "      B extends List<? extends String>,",
+        "      C extends List<? super String>> Factory<GenericClass<A, B, C>> create(",
+        "          Provider<A> aProvider, Provider<B> bProvider, Provider<C> cProvider) {",
+        "    return new GenericClass_Factory<A, B, C>(aProvider, bProvider, cProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void multipleSameTypesWithGenericsAndQualifiersAndLazies() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "import dagger.Lazy;",
+        "",
+        "class GenericClass<A, B> {",
+        "  @Inject GenericClass(A a, A a2, Provider<A> pa, @QualifierA A qa, Lazy<A> la, ",
+        "                       String s, String s2, Provider<String> ps, ",
+        "                       @QualifierA String qs, Lazy<String> ls,",
+        "                       B b, B b2, Provider<B> pb, @QualifierA B qb, Lazy<B> lb) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines("test.GenericClass_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.DoubleCheckLazy;",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> {",
+        "  private final Provider<A> aAndA2AndPaAndLaProvider;",
+        "  private final Provider<A> qaProvider;",
+        "  private final Provider<String> sAndS2AndPsAndLsProvider;",
+        "  private final Provider<String> qsProvider;",
+        "  private final Provider<B> bAndB2AndPbAndLbProvider;",
+        "  private final Provider<B> qbProvider;",
+        "",
+        "  public GenericClass_Factory(Provider<A> aAndA2AndPaAndLaProvider,",
+        "      Provider<A> qaProvider,", 
+        "      Provider<String> sAndS2AndPsAndLsProvider,",
+        "      Provider<String> qsProvider,",
+        "      Provider<B> bAndB2AndPbAndLbProvider,",
+        "      Provider<B> qbProvider) {",
+        "    assert aAndA2AndPaAndLaProvider != null;",
+        "    this.aAndA2AndPaAndLaProvider = aAndA2AndPaAndLaProvider;",
+        "    assert qaProvider != null;",
+        "    this.qaProvider = qaProvider;",
+        "    assert sAndS2AndPsAndLsProvider != null;",
+        "    this.sAndS2AndPsAndLsProvider = sAndS2AndPsAndLsProvider;",
+        "    assert qsProvider != null;",
+        "    this.qsProvider = qsProvider;",
+        "    assert bAndB2AndPbAndLbProvider != null;",
+        "    this.bAndB2AndPbAndLbProvider = bAndB2AndPbAndLbProvider;",
+        "    assert qbProvider != null;",
+        "    this.qbProvider = qbProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public GenericClass<A, B> get() {",
+        "    return new GenericClass<A, B>(",
+        "      aAndA2AndPaAndLaProvider.get(),",
+        "      aAndA2AndPaAndLaProvider.get(),",
+        "      aAndA2AndPaAndLaProvider,",
+        "      qaProvider.get(),",
+        "      DoubleCheckLazy.create(aAndA2AndPaAndLaProvider),",
+        "      sAndS2AndPsAndLsProvider.get(),",
+        "      sAndS2AndPsAndLsProvider.get(),",
+        "      sAndS2AndPsAndLsProvider,",
+        "      qsProvider.get(),",
+        "      DoubleCheckLazy.create(sAndS2AndPsAndLsProvider),",
+        "      bAndB2AndPbAndLbProvider.get(),",
+        "      bAndB2AndPbAndLbProvider.get(),", 
+        "      bAndB2AndPbAndLbProvider,",
+        "      qbProvider.get(),",
+        "      DoubleCheckLazy.create(bAndB2AndPbAndLbProvider));",
+        "  }",
+        "",
+        "  public static <A, B> Factory<GenericClass<A, B>> create(",
+        "      Provider<A> aAndA2AndPaAndLaProvider,",
+        "      Provider<A> qaProvider,", 
+        "      Provider<String> sAndS2AndPsAndLsProvider,",
+        "      Provider<String> qsProvider,",
+        "      Provider<B> bAndB2AndPbAndLbProvider,",
+        "      Provider<B> qbProvider) {",
+        "    return new GenericClass_Factory<A, B>(",
+        "        aAndA2AndPaAndLaProvider,",
+        "        qaProvider,",
+        "        sAndS2AndPsAndLsProvider,",
+        "        qsProvider,",
+        "        bAndB2AndPbAndLbProvider,",
+        "        qbProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void multipleInjectConstructors() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.TooManyInjectConstructors",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class TooManyInjectConstructors {",
+        "  @Inject TooManyInjectConstructors() {}",
+        "  TooManyInjectConstructors(int i) {}",
+        "  @Inject TooManyInjectConstructors(String s) {}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MULTIPLE_INJECT_CONSTRUCTORS).in(file).onLine(6)
+        .and().withErrorContaining(MULTIPLE_INJECT_CONSTRUCTORS).in(file).onLine(8);
+  }
+
+  @Test public void multipleQualifiersOnInjectConstructorParameter() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierConstructorParam",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class MultipleQualifierConstructorParam {",
+        "  @Inject MultipleQualifierConstructorParam(@QualifierA @QualifierB String s) {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor()).failsToCompile()
+        // for whatever reason, javac only reports the error once on the constructor
+        .withErrorContaining(MULTIPLE_QUALIFIERS).in(file).onLine(6);
+  }
+
+  @Test public void injectConstructorOnClassWithMultipleScopes() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "@ScopeA @ScopeB class MultipleScopeClass {",
+        "  @Inject MultipleScopeClass() {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, SCOPE_A, SCOPE_B))
+        .processedWith(new ComponentProcessor()).failsToCompile()
+        .withErrorContaining(MULTIPLE_SCOPES).in(file).onLine(5).atColumn(1)
+        .and().withErrorContaining(MULTIPLE_SCOPES).in(file).onLine(5).atColumn(9);
+  }
+
+  @Test public void injectConstructorWithQualifier() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class MultipleScopeClass {",
+        "  @Inject",
+        "  @QualifierA",
+        "  @QualifierB",
+        "  MultipleScopeClass() {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor()).failsToCompile()
+        .withErrorContaining(QUALIFIER_ON_INJECT_CONSTRUCTOR).in(file).onLine(7)
+        .and().withErrorContaining(QUALIFIER_ON_INJECT_CONSTRUCTOR).in(file).onLine(8);
+  }
+
+  @Test public void finalInjectField() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.FinalInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class FinalInjectField {",
+        "  @Inject final String s;",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(FINAL_INJECT_FIELD).in(file).onLine(6);
+  }
+
+  @Test public void privateInjectFieldError() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class PrivateInjectField {",
+        "  @Inject private String s;",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRIVATE_INJECT_FIELD).in(file).onLine(6);
+  }
+  
+  @Test public void privateInjectFieldWarning() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class PrivateInjectField {",
+        "  @Inject private String s;",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .withCompilerOptions("-Adagger.privateMemberValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError(); // TODO: Verify warning message when supported
+  }
+  
+  @Test public void staticInjectFieldError() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class StaticInjectField {",
+        "  @Inject static String s;",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(STATIC_INJECT_FIELD).in(file).onLine(6);
+  }
+  
+  @Test public void staticInjectFieldWarning() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class StaticInjectField {",
+        "  @Inject static String s;",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .withCompilerOptions("-Adagger.staticMemberValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError(); // TODO: Verify warning message when supported
+  }
+
+  @Test public void multipleQualifiersOnField() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierInjectField",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class MultipleQualifierInjectField {",
+        "  @Inject @QualifierA @QualifierB String s;",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor()).failsToCompile()
+        .withErrorContaining(MULTIPLE_QUALIFIERS).in(file).onLine(6).atColumn(11)
+        .and().withErrorContaining(MULTIPLE_QUALIFIERS).in(file).onLine(6).atColumn(23);
+  }
+
+  @Test public void abstractInjectMethod() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "abstract class AbstractInjectMethod {",
+        "  @Inject abstract void method();",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(ABSTRACT_INJECT_METHOD).in(file).onLine(6);
+  }
+
+  @Test public void privateInjectMethodError() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class PrivateInjectMethod {",
+        "  @Inject private void method(){}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRIVATE_INJECT_METHOD).in(file).onLine(6);
+  }
+  
+  @Test public void privateInjectMethodWarning() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class PrivateInjectMethod {",
+        "  @Inject private void method(){}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .withCompilerOptions("-Adagger.privateMemberValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError(); // TODO: Verify warning message when supported
+  }
+  
+  @Test public void staticInjectMethodError() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class StaticInjectMethod {",
+        "  @Inject static void method(){}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(STATIC_INJECT_METHOD).in(file).onLine(6);
+  }
+  
+  @Test public void staticInjectMethodWarning() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class StaticInjectMethod {",
+        "  @Inject static void method(){}",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .withCompilerOptions("-Adagger.staticMemberValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError(); // TODO: Verify warning message when supported
+  }
+
+  @Test public void genericInjectMethod() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericInjectMethod",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class AbstractInjectMethod {",
+        "  @Inject <T> void method();",
+        "}");
+    assertAbout(javaSource()).that(file)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(GENERIC_INJECT_METHOD).in(file).onLine(6);
+  }
+
+  @Test public void multipleQualifiersOnInjectMethodParameter() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierMethodParam",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class MultipleQualifierMethodParam {",
+        "  @Inject void method(@QualifierA @QualifierB String s) {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        // for whatever reason, javac only reports the error once on the method
+        .withErrorContaining(MULTIPLE_QUALIFIERS).in(file).onLine(6);
+  }
+
+  @Test public void injectConstructor() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class InjectConstructor {",
+        "  @Inject InjectConstructor(String s) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.InjectConstructor_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class InjectConstructor_Factory ",
+        "    implements Factory<InjectConstructor> {",
+        "",
+        "  private final Provider<String> sProvider;",
+        "",
+        "  public InjectConstructor_Factory(Provider<String> sProvider) {",
+        "    assert sProvider != null;",
+        "    this.sProvider = sProvider;",
+        "  }",
+        "",
+        "  @Override public InjectConstructor get() {",
+        "    return new InjectConstructor(sProvider.get());",
+        "  }",
+        "",
+        "  public static Factory<InjectConstructor> create(Provider<String> sProvider) {",
+        "    return new InjectConstructor_Factory(sProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test public void injectConstructorAndMembersInjection() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.AllInjections",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class AllInjections {",
+        "  @Inject String s;",
+        "  @Inject AllInjections(String s) {}",
+        "  @Inject void s(String s) {}",
+        "}");
+    JavaFileObject expectedFactory = JavaFileObjects.forSourceLines(
+        "test.AllInjections_Factory",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class AllInjections_Factory ",
+        "    implements Factory<AllInjections> {",
+        "",
+        "  private final MembersInjector<AllInjections> membersInjector;",
+        "  private final Provider<String> sProvider;",
+        "",
+        "  public AllInjections_Factory(MembersInjector<AllInjections> membersInjector, ",
+        "      Provider<String> sProvider) {",
+        "    assert membersInjector != null;",
+        "    this.membersInjector = membersInjector;",
+        "    assert sProvider != null;",
+        "    this.sProvider = sProvider;",
+        "  }",
+        "",
+        "  @Override public AllInjections get() {",
+        "    AllInjections instance = new AllInjections(sProvider.get());",
+        "    membersInjector.injectMembers(instance);",
+        "    return instance;",
+        "  }",
+        "",
+        "  public static Factory<AllInjections> create(",
+        "      MembersInjector<AllInjections> membersInjector, ",
+        "      Provider<String> sProvider) {",
+        "    return new AllInjections_Factory(membersInjector, sProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expectedFactory);
+  }
+
+  @Test public void supertypeRequiresMemberInjection() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "class A {}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class B extends A {",
+        "  @Inject B() {}",
+        "}");
+    JavaFileObject expectedFactory = JavaFileObjects.forSourceLines(
+        "test.B_Factory",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class B_Factory implements Factory<B> {",
+        "",
+        "  private final MembersInjector<B> membersInjector;",
+        "",
+        "  public B_Factory(MembersInjector<B> membersInjector) {",
+        "    assert membersInjector != null;",
+        "    this.membersInjector = membersInjector;",
+        "  }",
+        "",
+        "  @Override public B get() {",
+        "    B instance = new B();",
+        "    membersInjector.injectMembers(instance);",
+        "    return instance;",
+        "  }",
+        "",
+        "  public static Factory<B> create(MembersInjector<B> membersInjector) {",
+        "    return new B_Factory(membersInjector);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(aFile, bFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expectedFactory);
+  }
+
+  @Test
+  public void wildcardDependency() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
+        "package test;",
+        "",
+        "import java.util.List;",
+        "import javax.inject.Inject;",
+        "",
+        "class InjectConstructor {",
+        "  @Inject InjectConstructor(List<? extends Object> objects) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.InjectConstructor_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.List;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class InjectConstructor_Factory ",
+        "    implements Factory<InjectConstructor> {",
+        "",
+        "  private final Provider<List<? extends Object>> objectsProvider;",
+        "",
+        "  public InjectConstructor_Factory(Provider<List<? extends Object>> objectsProvider) {",
+        "    assert objectsProvider != null;",
+        "    this.objectsProvider = objectsProvider;",
+        "  }",
+        "",
+        "  @Override public InjectConstructor get() {",
+        "    return new InjectConstructor(objectsProvider.get());",
+        "  }",
+        "",
+        "  public static Factory<InjectConstructor> create(",
+        "      Provider<List<? extends Object>> objectsProvider) {",
+        "    return new InjectConstructor_Factory(objectsProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test
+  public void basicNameCollision() {
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Factory",
+        "package other.pkg;",
+        "",
+        "public class Factory {}");
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import other.pkg.Factory;",
+        "",
+        "class InjectConstructor {",
+        "  @Inject InjectConstructor(Factory factory) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.InjectConstructor_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class InjectConstructor_Factory ",
+        "    implements Factory<InjectConstructor> {",
+        "",
+        "  private final Provider<other.pkg.Factory> factoryProvider;",
+        "",
+        "  public InjectConstructor_Factory(Provider<other.pkg.Factory> factoryProvider) {",
+        "    assert factoryProvider != null;",
+        "    this.factoryProvider = factoryProvider;",
+        "  }",
+        "",
+        "  @Override public InjectConstructor get() {",
+        "    return new InjectConstructor(factoryProvider.get());",
+        "  }",
+        "",
+        "  public static Factory<InjectConstructor> create(",
+        "      Provider<other.pkg.Factory> factoryProvider) {",
+        "    return new InjectConstructor_Factory(factoryProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test
+  public void nestedNameCollision() {
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Outer",
+        "package other.pkg;",
+        "",
+        "public class Outer {",
+        "  public class Factory {}",
+        "}");
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "import other.pkg.Outer;",
+        "",
+        "class InjectConstructor {",
+        "  @Inject InjectConstructor(Outer.Factory factory) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.InjectConstructor_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "import other.pkg.Outer;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class InjectConstructor_Factory ",
+        "    implements Factory<InjectConstructor> {",
+        "",
+        "  private final Provider<Outer.Factory> factoryProvider;",
+        "",
+        "  public InjectConstructor_Factory(Provider<Outer.Factory> factoryProvider) {",
+        "    assert factoryProvider != null;",
+        "    this.factoryProvider = factoryProvider;",
+        "  }",
+        "",
+        "  @Override public InjectConstructor get() {",
+        "    return new InjectConstructor(factoryProvider.get());",
+        "  }",
+        "",
+        "  public static Factory<InjectConstructor> create(",
+        "      Provider<Outer.Factory> factoryProvider) {",
+        "    return new InjectConstructor_Factory(factoryProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test
+  public void samePackageNameCollision() {
+    JavaFileObject samePackageInterface = JavaFileObjects.forSourceLines("test.CommonName",
+        "package test;",
+        "",
+        "public interface CommonName {}");
+    JavaFileObject differentPackageInterface = JavaFileObjects.forSourceLines(
+        "other.pkg.CommonName",
+        "package other.pkg;",
+        "",
+        "public interface CommonName {}");
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class InjectConstructor implements CommonName {",
+        "  @Inject InjectConstructor(other.pkg.CommonName otherPackage, CommonName samePackage) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.InjectConstructor_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "import other.pkg.CommonName;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class InjectConstructor_Factory ",
+        "    implements Factory<InjectConstructor> {",
+        "",
+        "  private final Provider<CommonName> otherPackageProvider;",
+        "  private final Provider<test.CommonName> samePackageProvider;",
+        "",
+        "  public InjectConstructor_Factory(Provider<CommonName> otherPackageProvider,",
+        "      Provider<test.CommonName> samePackageProvider) {",
+        "    assert otherPackageProvider != null;",
+        "    this.otherPackageProvider = otherPackageProvider;",
+        "    assert samePackageProvider != null;",
+        "    this.samePackageProvider = samePackageProvider;",
+        "  }",
+        "",
+        "  @Override public InjectConstructor get() {",
+        "    return new InjectConstructor(otherPackageProvider.get(), samePackageProvider.get());",
+        "  }",
+        "",
+        "  public static Factory<InjectConstructor> create(",
+        "      Provider<CommonName> otherPackageProvider,",
+        "      Provider<test.CommonName> samePackageProvider) {",
+        "    return new InjectConstructor_Factory(otherPackageProvider, samePackageProvider);",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(samePackageInterface, differentPackageInterface, file))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expected);
+  }
+
+  @Test
+  public void noDeps() {
+    JavaFileObject simpleType = JavaFileObjects.forSourceLines("test.SimpleType",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class SimpleType {",
+        "  @Inject SimpleType() {}",
+        "}");
+    JavaFileObject factory = JavaFileObjects.forSourceLines("test.SimpleType_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public enum SimpleType_Factory implements Factory<SimpleType> {",
+        "  INSTANCE;",
+        "",
+        "  @Override public SimpleType get() {",
+        "    return new SimpleType();",
+        "  }",
+        "",
+        "  public static Factory<SimpleType> create() {",
+        "    return INSTANCE;",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(simpleType)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factory);
+  }
+
+  @Test public void simpleComponentWithNesting() {
+    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines("test.OuterType",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Inject;",
+        "",
+        "final class OuterType {",
+        "  static class A {",
+        "    @Inject A() {}",
+        "  }",
+        "  static class B {",
+        "    @Inject A a;",
+        "  }",
+        "  @Component interface SimpleComponent {",
+        "    A a();",
+        "    void inject(B b);",
+        "  }",
+        "}");
+    JavaFileObject aFactory = JavaFileObjects.forSourceLines(
+        "test.OuterType$A_Factory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "import test.OuterType.A;",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public enum OuterType$A_Factory implements Factory<A> {",
+        "  INSTANCE;",
+        "",
+        "  @Override public A get() {",
+        "    return new A();",
+        "  }",
+        "",
+        "  public static Factory<A> create() {",
+        "    return INSTANCE;",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(nestedTypesFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(aFactory);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/KeyTest.java b/compiler/src/test/java/dagger/internal/codegen/KeyTest.java
new file mode 100644
index 0000000..c1d622d
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/KeyTest.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.testing.compile.CompilationRule;
+import dagger.Module;
+import dagger.Provides;
+import dagger.producers.ProducerModule;
+import dagger.producers.Produces;
+import java.util.Set;
+import javax.inject.Inject;
+import javax.inject.Qualifier;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static dagger.Provides.Type.SET;
+import static dagger.Provides.Type.SET_VALUES;
+
+/**
+ * Tests {@link Key}.
+ */
+@RunWith(JUnit4.class)
+public class KeyTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  private Elements elements;
+  private Types types;
+  private Key.Factory keyFactory;
+
+  @Before public void setUp() {
+    this.types = compilationRule.getTypes();
+    this.elements = compilationRule.getElements();
+    this.keyFactory = new Key.Factory(types, elements);
+  }
+
+  @Test public void forInjectConstructorWithResolvedType() {
+    TypeElement typeElement =
+        compilationRule.getElements().getTypeElement(InjectedClass.class.getCanonicalName());
+    ExecutableElement constructor =
+        Iterables.getOnlyElement(ElementFilter.constructorsIn(typeElement.getEnclosedElements()));
+    assertThat(
+        keyFactory.forInjectConstructorWithResolvedType(constructor.getEnclosingElement().asType()))
+        .isEqualTo(new AutoValue_Key(
+            Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+            MoreTypes.equivalence().wrap(typeElement.asType())));
+  }
+
+  static final class InjectedClass {
+    @SuppressWarnings("unused")
+    @Inject InjectedClass(String s, int i) {}
+  }
+
+  @Test public void forProvidesMethod() {
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeElement moduleElement =
+        elements.getTypeElement(ProvidesMethodModule.class.getCanonicalName());
+    ExecutableElement providesMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
+    assertThat(
+        keyFactory.forProvidesMethod((ExecutableType) providesMethod.asType(), providesMethod))
+        .isEqualTo(new AutoValue_Key(
+            Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+            MoreTypes.equivalence().wrap(stringType)));
+  }
+
+  @Module
+  static final class ProvidesMethodModule {
+    @Provides String provideString() {
+      return null;
+    }
+  }
+
+  @Test public void forProvidesMethod_qualified() {
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeElement qualifierElement =
+        elements.getTypeElement(TestQualifier.class.getCanonicalName());
+    TypeElement moduleElement =
+        elements.getTypeElement(QualifiedProvidesMethodModule.class.getCanonicalName());
+    ExecutableElement providesMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
+    Key key =
+        keyFactory.forProvidesMethod((ExecutableType) providesMethod.asType(), providesMethod);
+    assertThat(MoreTypes.equivalence().wrap(key.qualifier().get().getAnnotationType()))
+        .isEqualTo(MoreTypes.equivalence().wrap(qualifierElement.asType()));
+    assertThat(key.wrappedType()).isEqualTo(MoreTypes.equivalence().wrap(stringType));
+  }
+
+  @Test public void qualifiedKeyEquivalents() {
+    TypeElement moduleElement =
+        elements.getTypeElement(QualifiedProvidesMethodModule.class.getCanonicalName());
+    ExecutableElement providesMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
+    Key provisionKey =
+        keyFactory.forProvidesMethod((ExecutableType) providesMethod.asType(), providesMethod);
+
+    TypeMirror type = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeElement injectableElement =
+        elements.getTypeElement(QualifiedFieldHolder.class.getCanonicalName());
+    Element injectionField =
+        Iterables.getOnlyElement(ElementFilter.fieldsIn(injectableElement.getEnclosedElements()));
+    AnnotationMirror qualifier = Iterables.getOnlyElement(injectionField.getAnnotationMirrors());
+    Key injectionKey = keyFactory.forQualifiedType(Optional.<AnnotationMirror>of(qualifier), type);
+
+    assertThat(provisionKey).isEqualTo(injectionKey);
+  }
+
+  @Module
+  static final class QualifiedProvidesMethodModule {
+    @Provides
+    @TestQualifier(@InnerAnnotation)
+    String provideQualifiedString() {
+      return null;
+    }
+  }
+
+  static final class QualifiedFieldHolder {
+    @TestQualifier(@InnerAnnotation) String aString;
+  }
+
+  @Qualifier
+  @interface TestQualifier {
+    InnerAnnotation[] value();
+  }
+
+  @interface InnerAnnotation {}
+
+  @Test public void forProvidesMethod_sets() {
+    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeMirror setOfStringsType = types.getDeclaredType(setElement, stringType);
+    TypeElement moduleElement =
+        elements.getTypeElement(SetProvidesMethodsModule.class.getCanonicalName());
+    for (ExecutableElement providesMethod
+        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
+      assertThat(
+          keyFactory.forProvidesMethod((ExecutableType) providesMethod.asType(), providesMethod))
+              .isEqualTo(new AutoValue_Key(
+                  Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+                  MoreTypes.equivalence().wrap(setOfStringsType)));
+    }
+  }
+
+  @Module
+  static final class SetProvidesMethodsModule {
+    @Provides(type = SET) String provideString() {
+      return null;
+    }
+
+    @Provides(type = SET_VALUES) Set<String> provideStrings() {
+      return null;
+    }
+  }
+
+  @Module
+  static final class PrimitiveTypes {
+    @Provides int foo() {
+      return 0;
+    }
+  }
+
+  @Module
+  static final class BoxedPrimitiveTypes {
+    @Provides Integer foo() {
+      return 0;
+    }
+  }
+
+  @Test public void primitiveKeysMatchBoxedKeys() {
+    TypeElement primitiveHolder = elements.getTypeElement(PrimitiveTypes.class.getCanonicalName());
+    ExecutableElement intMethod =
+        Iterables.getOnlyElement(ElementFilter.methodsIn(primitiveHolder.getEnclosedElements()));
+    TypeElement boxedPrimitiveHolder =
+        elements.getTypeElement(BoxedPrimitiveTypes.class.getCanonicalName());
+    ExecutableElement integerMethod = Iterables.getOnlyElement(
+        ElementFilter.methodsIn(boxedPrimitiveHolder.getEnclosedElements()));
+
+    // TODO(cgruber): Truth subject for TypeMirror and TypeElement
+    TypeMirror intType = intMethod.getReturnType();
+    assertThat(intType.getKind().isPrimitive()).isTrue();
+    TypeMirror integerType = integerMethod.getReturnType();
+    assertThat(integerType.getKind().isPrimitive()).isFalse();
+    assertThat(types.isSameType(intType, integerType)).named("type equality").isFalse();
+
+    Key intKey = keyFactory.forProvidesMethod((ExecutableType) intMethod.asType(), intMethod);
+    Key integerKey =
+        keyFactory.forProvidesMethod((ExecutableType) integerMethod.asType(), integerMethod);
+    assertThat(intKey).isEqualTo(integerKey);
+  }
+
+  @Test public void forProducesMethod() {
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeElement moduleElement =
+        elements.getTypeElement(ProducesMethodsModule.class.getCanonicalName());
+    for (ExecutableElement producesMethod
+        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
+      assertThat(keyFactory.forProducesMethod(
+          (ExecutableType) producesMethod.asType(), producesMethod))
+              .isEqualTo(new AutoValue_Key(
+                  Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+                  MoreTypes.equivalence().wrap(stringType)));
+    }
+  }
+
+  @ProducerModule
+  static final class ProducesMethodsModule {
+    @Produces String produceString() {
+      return null;
+    }
+
+    @Produces ListenableFuture<String> produceFutureString() {
+      return null;
+    }
+  }
+
+  @Test public void forProducesMethod_sets() {
+    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeMirror setOfStringsType = types.getDeclaredType(setElement, stringType);
+    TypeElement moduleElement =
+        elements.getTypeElement(SetProducesMethodsModule.class.getCanonicalName());
+    for (ExecutableElement producesMethod
+        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
+      assertThat(keyFactory.forProducesMethod(
+          (ExecutableType) producesMethod.asType(), producesMethod))
+          .isEqualTo(new AutoValue_Key(
+                  Optional.<Equivalence.Wrapper<AnnotationMirror>>absent(),
+                  MoreTypes.equivalence().wrap(setOfStringsType)));
+    }
+  }
+
+  @ProducerModule
+  static final class SetProducesMethodsModule {
+    @Produces(type = Produces.Type.SET) String produceString() {
+      return null;
+    }
+
+    @Produces(type = Produces.Type.SET) ListenableFuture<String> produceFutureString() {
+      return null;
+    }
+
+    @Produces(type = Produces.Type.SET_VALUES) Set<String> produceStrings() {
+      return null;
+    }
+
+    @Produces(type = Produces.Type.SET_VALUES)
+    ListenableFuture<Set<String>> produceFutureStrings() {
+      return null;
+    }
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MapBindingComponentProcessorTest.java b/compiler/src/test/java/dagger/internal/codegen/MapBindingComponentProcessorTest.java
new file mode 100644
index 0000000..9e1b6dc
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MapBindingComponentProcessorTest.java
@@ -0,0 +1,906 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.value.processor.AutoAnnotationProcessor;
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class MapBindingComponentProcessorTest {
+
+  @Test
+  public void mapBindingsWithEnumKey() {
+    JavaFileObject mapModuleOneFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleOne",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "",
+                "@Module",
+                "final class MapModuleOne {",
+                "  @Provides(type = MAP) @PathKey(PathEnum.ADMIN) Handler provideAdminHandler() {",
+                "    return new AdminHandler();",
+                "  }",
+                "}");
+    JavaFileObject mapModuleTwoFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleTwo",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "",
+                "@Module",
+                "final class MapModuleTwo {",
+                "  @Provides(type = MAP) @PathKey(PathEnum.LOGIN) Handler provideLoginHandler() {",
+                "    return new LoginHandler();",
+                "  }",
+                "}");
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = true)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+
+    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<PathEnum, Provider<Handler>> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfPathEnumAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfPathEnumAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<PathEnum, Provider<Handler>>>",
+        "      mapOfPathEnumAndProviderOfHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfPathEnumAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfPathEnumAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfPathEnumAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<PathEnum, Handler>builder(2)",
+        "            .put(PathEnum.ADMIN,",
+        "                mapOfPathEnumAndProviderOfHandlerContribution1)",
+        "            .put(PathEnum.LOGIN,",
+        "                mapOfPathEnumAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<PathEnum, Provider<Handler>> dispatcher() {",
+        "    return mapOfPathEnumAndProviderOfHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(mapModuleOneFile,
+            mapModuleTwoFile,
+            enumKeyFile,
+            pathEnumFile,
+            HandlerFile,
+            LoginHandlerFile,
+            AdminHandlerFile,
+            componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void mapBindingsWithStringKey() {
+    JavaFileObject mapModuleOneFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleOne",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "import dagger.mapkeys.StringKey;",
+                "",
+                "@Module",
+                "final class MapModuleOne {",
+                "  @Provides(type = MAP) @StringKey(\"Admin\") Handler provideAdminHandler() {",
+                "    return new AdminHandler();",
+                "  }",
+                "}");
+    JavaFileObject mapModuleTwoFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleTwo",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "import dagger.mapkeys.StringKey;",
+                "",
+                "@Module",
+                "final class MapModuleTwo {",
+                "  @Provides(type = MAP) @StringKey(\"Login\") Handler provideLoginHandler() {",
+                "    return new LoginHandler();",
+                "  }",
+                "}");
+    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<String, Provider<Handler>> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfStringAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfStringAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<String, Provider<Handler>>>",
+        "      mapOfStringAndProviderOfHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfStringAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfStringAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfStringAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<String, Handler>builder(2)",
+        "            .put(\"Admin\", mapOfStringAndProviderOfHandlerContribution1)",
+        "            .put(\"Login\", mapOfStringAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<String, Provider<Handler>> dispatcher() {",
+        "    return mapOfStringAndProviderOfHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(mapModuleOneFile,
+            mapModuleTwoFile,
+            HandlerFile,
+            LoginHandlerFile,
+            AdminHandlerFile,
+            componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void mapBindingsWithWrappedKey() {
+    JavaFileObject mapModuleOneFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleOne",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "",
+                "@Module",
+                "final class MapModuleOne {",
+                "  @Provides(type = MAP)",
+                "  @WrappedClassKey(Integer.class) Handler provideAdminHandler() {",
+                "    return new AdminHandler();",
+                "  }",
+                "}");
+    JavaFileObject mapModuleTwoFile =
+        JavaFileObjects
+            .forSourceLines("test.MapModuleTwo",
+                "package test;",
+                "",
+                "import static dagger.Provides.Type.MAP;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "",
+                "@Module",
+                "final class MapModuleTwo {",
+                "  @Provides(type = MAP)",
+                "  @WrappedClassKey(Long.class) Handler provideLoginHandler() {",
+                "    return new LoginHandler();",
+                "  }",
+                "}");
+    JavaFileObject wrappedClassKeyFile = JavaFileObjects.forSourceLines("test.WrappedClassKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = false)",
+        "@Retention(RUNTIME)",
+        "public @interface WrappedClassKey {",
+        "  Class<?> value();",
+        "}");
+    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<WrappedClassKey, Provider<Handler>> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfWrappedClassKeyAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfWrappedClassKeyAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<WrappedClassKey, Provider<Handler>>>",
+        "      mapOfWrappedClassKeyAndProviderOfHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfWrappedClassKeyAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfWrappedClassKeyAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfWrappedClassKeyAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<WrappedClassKey, Handler>builder(2)",
+        "            .put(WrappedClassKeyCreator.createWrappedClassKey(Integer.class),",
+        "                mapOfWrappedClassKeyAndProviderOfHandlerContribution1)",
+        "            .put(WrappedClassKeyCreator.createWrappedClassKey(Long.class),",
+        "                mapOfWrappedClassKeyAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<WrappedClassKey, Provider<Handler>> dispatcher() {",
+        "    return mapOfWrappedClassKeyAndProviderOfHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(mapModuleOneFile,
+            mapModuleTwoFile,
+            wrappedClassKeyFile,
+            HandlerFile,
+            LoginHandlerFile,
+            AdminHandlerFile,
+            componentFile))
+        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void mapBindingsWithNonProviderValue() {
+    JavaFileObject mapModuleOneFile = JavaFileObjects.forSourceLines("test.MapModuleOne",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleOne {",
+        "  @Provides(type = MAP) @PathKey(PathEnum.ADMIN) Handler provideAdminHandler() {",
+        "    return new AdminHandler();",
+        "  }",
+        "}");
+    JavaFileObject mapModuleTwoFile = JavaFileObjects.forSourceLines("test.MapModuleTwo",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleTwo {",
+        "  @Provides(type = MAP) @PathKey(PathEnum.LOGIN) Handler provideLoginHandler() {",
+        "    return new LoginHandler();",
+        "  }",
+        "}");
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = true)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<PathEnum, Handler> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapFactory;",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfPathEnumAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfPathEnumAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<PathEnum, Provider<Handler>>>",
+        "      mapOfPathEnumAndProviderOfHandlerProvider;",
+        "  private Provider<Map<PathEnum, Handler>> mapOfPathEnumAndHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfPathEnumAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfPathEnumAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfPathEnumAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<PathEnum, Handler>builder(2)",
+        "            .put(PathEnum.ADMIN,",
+        "                mapOfPathEnumAndProviderOfHandlerContribution1)",
+        "            .put(PathEnum.LOGIN,",
+        "                mapOfPathEnumAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "    this.mapOfPathEnumAndHandlerProvider =",
+        "        MapFactory.create(mapOfPathEnumAndProviderOfHandlerProvider);",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<PathEnum, Handler> dispatcher() {",
+        "    return mapOfPathEnumAndHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(mapModuleOneFile,
+            mapModuleTwoFile,
+            enumKeyFile,
+            pathEnumFile,
+            HandlerFile,
+            LoginHandlerFile,
+            AdminHandlerFile,
+            componentFile)).
+        processedWith(new ComponentProcessor())
+            .compilesWithoutError()
+            .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void injectMapWithoutMapBinding() {
+    JavaFileObject mapModuleFile = JavaFileObjects.forSourceLines("test.MapModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.HashMap;",
+        "import java.util.Map;",
+        "",
+        "@Module",
+        "final class MapModule {",
+        "  @Provides Map<String, String> provideAMap() {",
+        "    Map<String, String> map = new HashMap<String, String>();",
+        "    map.put(\"Hello\", \"World\");",
+        "    return map;",
+        "  }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "",
+        "@Component(modules = {MapModule.class})",
+        "interface TestComponent {",
+        "  Map<String, String> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Map<String, String>> provideAMapProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.provideAMapProvider = MapModule_ProvideAMapFactory.create(builder.mapModule);",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<String, String> dispatcher() {",
+        "    return provideAMapProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModule mapModule;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModule == null) {",
+        "        this.mapModule = new MapModule();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModule(MapModule mapModule) {",
+        "      if (mapModule == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModule = mapModule;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(mapModuleFile,componentFile))
+        .processedWith(new ComponentProcessor()).compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void mapBindingsWithDuplicateKeys() {
+    JavaFileObject module =
+        JavaFileObjects.forSourceLines(
+            "test.MapModule",
+            "package test;",
+            "",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import dagger.mapkeys.StringKey;",
+            "",
+            "import static dagger.Provides.Type.MAP;",
+            "",
+            "@Module",
+            "final class MapModule {",
+            "  @Provides(type = MAP) @StringKey(\"AKey\") Object provideObjectForAKey() {",
+            "    return \"one\";",
+            "  }",
+            "",
+            "  @Provides(type = MAP) @StringKey(\"AKey\") Object provideObjectForAKeyAgain() {",
+            "    return \"one again\";",
+            "  }",
+            "}");
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import java.util.Map;",
+            "import javax.inject.Provider;",
+            "",
+            "@Component(modules = {MapModule.class})",
+            "interface TestComponent {",
+            "  Map<String, Object> objects();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(module, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("The same map key is bound more than once")
+        .and()
+        .withErrorContaining("provideObjectForAKey()")
+        .and()
+        .withErrorContaining("provideObjectForAKeyAgain()")
+        .and()
+        .withErrorCount(1);
+  }
+
+  @Test
+  public void mapBindingsWithInconsistentKeyAnnotations() {
+    JavaFileObject module =
+        JavaFileObjects.forSourceLines(
+            "test.MapModule",
+            "package test;",
+            "",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import dagger.mapkeys.StringKey;",
+            "",
+            "import static dagger.Provides.Type.MAP;",
+            "",
+            "@Module",
+            "final class MapModule {",
+            "  @Provides(type = MAP) @StringKey(\"AKey\") Object provideObjectForAKey() {",
+            "    return \"one\";",
+            "  }",
+            "",
+            "  @Provides(type = MAP) @StringKeyTwo(\"BKey\") Object provideObjectForBKey() {",
+            "    return \"two\";",
+            "  }",
+            "}");
+    JavaFileObject stringKeyTwoFile =
+        JavaFileObjects.forSourceLines(
+            "test.StringKeyTwo",
+            "package test;",
+            "",
+            "import dagger.MapKey;",
+            "",
+            "@MapKey(unwrapValue = true)",
+            "public @interface StringKeyTwo {",
+            "  String value();",
+            "}");
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import java.util.Map;",
+            "",
+            "@Component(modules = {MapModule.class})",
+            "interface TestComponent {",
+            "  Map<String, Object> objects();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(module, stringKeyTwoFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("uses more than one @MapKey annotation type")
+        .and()
+        .withErrorContaining("provideObjectForAKey()")
+        .and()
+        .withErrorContaining("provideObjectForBKey()")
+        .and()
+        .withErrorCount(1);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MapKeyProcessorTest.java b/compiler/src/test/java/dagger/internal/codegen/MapKeyProcessorTest.java
new file mode 100644
index 0000000..191ee6c
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MapKeyProcessorTest.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.auto.value.processor.AutoAnnotationProcessor;
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class MapKeyProcessorTest {
+  @Test
+  public void mapKeyCreatorFile() {
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = false)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "  String relativePath() default \"Defaultpath\";",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+    JavaFileObject generatedKeyCreator =
+        JavaFileObjects.forSourceLines(
+            "test.PathKeyCreator",
+            "package test;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "import javax.annotation.Generated;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class PathKeyCreator {",
+            "  @AutoAnnotation",
+            "  public static PathKey createPathKey(PathEnum value, String relativePath) {",
+            "    return new AutoAnnotation_PathKeyCreator_createPathKey(value, relativePath);",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(enumKeyFile, pathEnumFile))
+        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedKeyCreator);
+  }
+
+  @Test
+  public void nestedMapKeyCreatorFile() {
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.Container",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "public interface Container {",
+        "@MapKey(unwrapValue = false)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "  String relativePath() default \"Defaultpath\";",
+        "}",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+    JavaFileObject generatedKeyCreator =
+        JavaFileObjects.forSourceLines(
+            "test.Container$PathKeyCreator",
+            "package test;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "import javax.annotation.Generated;",
+            "import test.Container.PathKey",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class Container$PathKeyCreator {",
+            "  @AutoAnnotation",
+            "  public static PathKey createPathKey(PathEnum value, String relativePath) {",
+            "    return new AutoAnnotation_Container$PathKeyCreator_createPathKey(",
+            "        value, relativePath);",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(enumKeyFile, pathEnumFile))
+        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedKeyCreator);
+  }
+
+  @Test
+  public void mapKeyComponentFileWithDisorderedKeyField() {
+    JavaFileObject mapModuleOneFile = JavaFileObjects.forSourceLines("test.MapModuleOne",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleOne {",
+        "  @Provides(type = MAP) @PathKey(relativePath = \"AdminPath\", value = PathEnum.ADMIN)",
+        "      Handler provideAdminHandler() {",
+        "    return new AdminHandler();",
+        "  }",
+        "}");
+    JavaFileObject mapModuleTwoFile =JavaFileObjects.forSourceLines("test.MapModuleTwo",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleTwo {",
+        "  @Provides(type = MAP) @PathKey(value = PathEnum.LOGIN, relativePath = \"LoginPath\")",
+        "      Handler provideLoginHandler() {",
+        "    return new LoginHandler();",
+        "  }",
+        "}");
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = false)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "  String relativePath() default \"DefaultPath\";",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+    JavaFileObject handlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject loginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject adminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<PathKey, Provider<Handler>> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfPathKeyAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfPathKeyAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<PathKey, Provider<Handler>>>",
+        "      mapOfPathKeyAndProviderOfHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfPathKeyAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfPathKeyAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfPathKeyAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<PathKey, Handler>builder(2)",
+        "            .put(PathKeyCreator.createPathKey(PathEnum.ADMIN, \"AdminPath\"),",
+        "                mapOfPathKeyAndProviderOfHandlerContribution1)",
+        "            .put(PathKeyCreator.createPathKey(PathEnum.LOGIN, \"LoginPath\"),",
+        "                mapOfPathKeyAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<PathKey, Provider<Handler>> dispatcher() {",
+        "    return mapOfPathKeyAndProviderOfHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(
+            ImmutableList.of(
+                mapModuleOneFile,
+                mapModuleTwoFile,
+                enumKeyFile,
+                pathEnumFile,
+                handlerFile,
+                loginHandlerFile,
+                adminHandlerFile,
+                componentFile))
+        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void mapKeyComponentFileWithDefaultField() {
+    JavaFileObject mapModuleOneFile = JavaFileObjects.forSourceLines("test.MapModuleOne",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleOne {",
+        "  @Provides(type = MAP) @PathKey(value = PathEnum.ADMIN) Handler provideAdminHandler() {",
+        "    return new AdminHandler();",
+        "  }",
+        "}");
+    JavaFileObject mapModuleTwoFile =JavaFileObjects.forSourceLines("test.MapModuleTwo",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.MAP;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class MapModuleTwo {",
+        "  @Provides(type = MAP) @PathKey(value = PathEnum.LOGIN, relativePath = \"LoginPath\")",
+        "      Handler provideLoginHandler() {",
+        "    return new LoginHandler();",
+        "  }",
+        "}");
+    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
+        "package test;",
+        "import dagger.MapKey;",
+        "import java.lang.annotation.Retention;",
+        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
+        "",
+        "@MapKey(unwrapValue = false)",
+        "@Retention(RUNTIME)",
+        "public @interface PathKey {",
+        "  PathEnum value();",
+        "  String relativePath() default \"DefaultPath\";",
+        "}");
+    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
+        "package test;",
+        "",
+        "public enum PathEnum {",
+        "    ADMIN,",
+        "    LOGIN;",
+        "}");
+    JavaFileObject handlerFile = JavaFileObjects.forSourceLines("test.Handler",
+        "package test;",
+        "",
+        "interface Handler {}");
+    JavaFileObject loginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
+        "package test;",
+        "",
+        "class LoginHandler implements Handler {",
+        "  public LoginHandler() {}",
+        "}");
+    JavaFileObject adminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
+        "package test;",
+        "",
+        "class AdminHandler implements Handler {",
+        "  public AdminHandler() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.Map;",
+        "import javax.inject.Provider;",
+        "",
+        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
+        "interface TestComponent {",
+        "  Map<PathKey, Provider<Handler>> dispatcher();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines("test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.internal.MapProviderFactory;",
+        "import java.util.Map;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Handler> mapOfPathKeyAndProviderOfHandlerContribution1;",
+        "  private Provider<Handler> mapOfPathKeyAndProviderOfHandlerContribution2;",
+        "  private Provider<Map<PathKey, Provider<Handler>>>",
+        "      mapOfPathKeyAndProviderOfHandlerProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.mapOfPathKeyAndProviderOfHandlerContribution1 =",
+        "        MapModuleOne_ProvideAdminHandlerFactory.create(builder.mapModuleOne);",
+        "    this.mapOfPathKeyAndProviderOfHandlerContribution2 =",
+        "        MapModuleTwo_ProvideLoginHandlerFactory.create(builder.mapModuleTwo);",
+        "    this.mapOfPathKeyAndProviderOfHandlerProvider =",
+        "        MapProviderFactory.<PathKey, Handler>builder(2)",
+        "            .put(PathKeyCreator.createPathKey(PathEnum.ADMIN, \"DefaultPath\"),",
+        "                mapOfPathKeyAndProviderOfHandlerContribution1)",
+        "            .put(PathKeyCreator.createPathKey(PathEnum.LOGIN, \"LoginPath\"),",
+        "                mapOfPathKeyAndProviderOfHandlerContribution2)",
+        "            .build();",
+        "  }",
+        "",
+        "  @Override",
+        "  public Map<PathKey, Provider<Handler>> dispatcher() {",
+        "    return mapOfPathKeyAndProviderOfHandlerProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private MapModuleOne mapModuleOne;",
+        "    private MapModuleTwo mapModuleTwo;",
+        "",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      if (mapModuleOne == null) {",
+        "        this.mapModuleOne = new MapModuleOne();",
+        "      }",
+        "      if (mapModuleTwo == null) {",
+        "        this.mapModuleTwo = new MapModuleTwo();",
+        "      }",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "",
+        "    public Builder mapModuleOne(MapModuleOne mapModuleOne) {",
+        "      if (mapModuleOne == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleOne = mapModuleOne;",
+        "      return this;",
+        "    }",
+        "",
+        "    public Builder mapModuleTwo(MapModuleTwo mapModuleTwo) {",
+        "      if (mapModuleTwo == null) {",
+        "        throw new NullPointerException();",
+        "      }",
+        "      this.mapModuleTwo = mapModuleTwo;",
+        "      return this;",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(
+            ImmutableList.of(
+                mapModuleOneFile,
+                mapModuleTwoFile,
+                enumKeyFile,
+                pathEnumFile,
+                handlerFile,
+                loginHandlerFile,
+                adminHandlerFile,
+                componentFile))
+        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MembersInjectionTest.java b/compiler/src/test/java/dagger/internal/codegen/MembersInjectionTest.java
new file mode 100644
index 0000000..52be72a
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MembersInjectionTest.java
@@ -0,0 +1,921 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.testing.compile.JavaFileObjects;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+
+@RunWith(JUnit4.class)
+public class MembersInjectionTest {
+  @Test
+  public void parentClass_noInjectedMembers() {
+    JavaFileObject childFile = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public final class Child extends Parent {",
+        "  @Inject Child() {}",
+        "}");
+    JavaFileObject parentFile = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "public abstract class Parent {}");
+
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  Child child();",
+        "}");
+    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
+        "test.DaggerTestComponent",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.MembersInjectors;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class DaggerTestComponent implements TestComponent {",
+        "  private Provider<Child> childProvider;",
+        "",
+        "  private DaggerTestComponent(Builder builder) {",
+        "    assert builder != null;",
+        "    initialize(builder);",
+        "  }",
+        "",
+        "  public static Builder builder() {",
+        "    return new Builder();",
+        "  }",
+        "",
+        "  public static TestComponent create() {",
+        "    return builder().build();",
+        "  }",
+        "",
+        "  @SuppressWarnings(\"unchecked\")",
+        "  private void initialize(final Builder builder) {",
+        "    this.childProvider =",
+        "        Child_Factory.create((MembersInjector) MembersInjectors.noOp());",
+        "  }",
+        "",
+        "  @Override",
+        "  public Child child() {",
+        "    return childProvider.get();",
+        "  }",
+        "",
+        "  public static final class Builder {",
+        "    private Builder() {",
+        "    }",
+        "",
+        "    public TestComponent build() {",
+        "      return new DaggerTestComponent(this);",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(childFile, parentFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+
+  @Test
+  public void parentClass_injectedMembersInSupertype() {
+    JavaFileObject childFile = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public final class Child extends Parent {",
+        "  @Inject Child() {}",
+        "}");
+    JavaFileObject parentFile = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "public abstract class Parent {",
+        "  @Inject Dep dep;",
+        "}");
+    JavaFileObject depFile = JavaFileObjects.forSourceLines("test.Dep",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class Dep {",
+        "  @Inject Dep() {}",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  Child child();",
+        "}");
+    JavaFileObject generatedComponent =
+        JavaFileObjects.forSourceLines(
+            "test.DaggerTestComponent",
+            "package test;",
+            "",
+            "import dagger.MembersInjector;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class DaggerTestComponent implements TestComponent {",
+            "  private MembersInjector<Child> childMembersInjector;",
+            "  private Provider<Child> childProvider;",
+            "",
+            "  private DaggerTestComponent(Builder builder) {",
+            "    assert builder != null;",
+            "    initialize(builder);",
+            "  }",
+            "",
+            "  public static Builder builder() {",
+            "    return new Builder();",
+            "  }",
+            "",
+            "  public static TestComponent create() {",
+            "    return builder().build();",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\")",
+            "  private void initialize(final Builder builder) {",
+            "    this.childMembersInjector = Child_MembersInjector.create(Dep_Factory.create());",
+            "    this.childProvider = Child_Factory.create(childMembersInjector);",
+            "  }",
+            "",
+            "  @Override",
+            "  public Child child() {",
+            "    return childProvider.get();",
+            "  }",
+            "",
+            "  public static final class Builder {",
+            "    private Builder() {}",
+            "",
+            "    public TestComponent build() {",
+            "      return new DaggerTestComponent(this);",
+            "    }",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(childFile, parentFile, depFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(generatedComponent);
+  }
+
+  @Test public void fieldAndMethodGenerics() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class GenericClass<A, B> {",
+        "  @Inject A a;",
+        "",
+        "  @Inject GenericClass() {}",
+        "",
+        " @Inject void register(B b) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.GenericClass_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class GenericClass_MembersInjector<A, B>",
+        "    implements MembersInjector<GenericClass<A, B>> {",
+        "  private final Provider<A> aProvider;",
+        "  private final Provider<B> bProvider;",
+        "",
+        "  public GenericClass_MembersInjector(Provider<A> aProvider, Provider<B> bProvider) {",
+        "    assert aProvider != null;",
+        "    this.aProvider = aProvider;",
+        "    assert bProvider != null;",
+        "    this.bProvider = bProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(GenericClass<A, B> instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.a = aProvider.get();",
+        "    instance.register(bProvider.get());",
+        "  }",
+        "",
+        "  public static <A, B> MembersInjector<GenericClass<A, B>> create(",
+        "      Provider<A> aProvider, Provider<B> bProvider) {",
+        "    return new GenericClass_MembersInjector<A, B>(aProvider, bProvider);",
+        "  }",
+        "",
+        "  public static <A, B> void injectA(GenericClass<A, B> instance, Provider<A> aProvider) {",
+        "    instance.a = aProvider.get();",
+        "  }",
+        "",
+        "  public static <A, B> void injectRegister(",
+        "      GenericClass<A, B> instance, Provider<B> bProvider) {",
+        "    instance.register(bProvider.get());",
+        "  }",
+        "",
+        "}");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test public void subclassedGenericMembersInjectors() {
+    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A {",
+        "  @Inject A() {}",
+        "}");
+    JavaFileObject a2 = JavaFileObjects.forSourceLines("test.A2",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "final class A2 {",
+        "  @Inject A2() {}",
+        "}");
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class Parent<X, Y> {",
+        "  @Inject X x;",
+        "  @Inject Y y;",
+        "  @Inject A2 a2;",
+        "",
+        "  @Inject Parent() {}",
+        "}");
+    JavaFileObject child = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class Child<T> extends Parent<T, A> {",
+        "  @Inject A a;",
+        "  @Inject T t;",
+        "",
+        "  @Inject Child() {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.Child_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class Child_MembersInjector<T>",
+        "    implements MembersInjector<Child<T>> {",
+        "  private final Provider<T> tAndXProvider;",
+        "  private final Provider<A> aAndYProvider;",
+        "  private final Provider<A2> a2Provider;",
+        "",
+        "  public Child_MembersInjector(",
+        "      Provider<T> tAndXProvider, Provider<A> aAndYProvider, Provider<A2> a2Provider) {",
+        "    assert tAndXProvider != null;",
+        "    this.tAndXProvider = tAndXProvider;",
+        "    assert aAndYProvider != null;",
+        "    this.aAndYProvider = aAndYProvider;",
+        "    assert a2Provider != null;",
+        "    this.a2Provider = a2Provider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(Child<T> instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    ((test.Parent) instance).x = tAndXProvider.get();",
+        "    ((test.Parent) instance).y = aAndYProvider.get();",
+        "    ((test.Parent) instance).a2 = a2Provider.get();",
+        "    instance.a = aAndYProvider.get();",
+        "    instance.t = tAndXProvider.get();",
+        "  }",
+        "",
+        "  public static <T> MembersInjector<Child<T>> create(",
+        "      Provider<T> tAndXProvider, Provider<A> aAndYProvider, Provider<A2> a2Provider) {",
+        "    return new Child_MembersInjector<T>(tAndXProvider, aAndYProvider, a2Provider);",
+        "  }",
+        "",
+        "  public static <T> void injectA(Child<T> instance, Provider<A> aProvider) {",
+        "    instance.a = aProvider.get();",
+        "  }",
+        "",
+        "  public static <T> void injectT(Child<T> instance, Provider<T> tProvider) {",
+        "    instance.t = tProvider.get();",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(a, a2, parent, child))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test public void fieldInjection() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.FieldInjection",
+        "package test;",
+        "",
+        "import dagger.Lazy;",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "class FieldInjection {",
+        "  @Inject String string;",
+        "  @Inject Lazy<String> lazyString;",
+        "  @Inject Provider<String> stringProvider;",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.FieldInjection_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.DoubleCheckLazy;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class FieldInjection_MembersInjector",
+        "    implements MembersInjector<FieldInjection> {",
+        "  private final Provider<String> stringProvider;",
+        "",
+        "  public FieldInjection_MembersInjector(Provider<String> stringProvider) {",
+        "    assert stringProvider != null;",
+        "    this.stringProvider = stringProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(FieldInjection instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.string = stringProvider.get();",
+        "    instance.lazyString = DoubleCheckLazy.create(stringProvider);",
+        "    instance.stringProvider = stringProvider;",
+        "  }",
+        "",
+        "  public static MembersInjector<FieldInjection> create(Provider<String> stringProvider) {",
+        "    return new FieldInjection_MembersInjector(stringProvider);",
+        "  }",
+        "",
+        "  public static void injectString(",
+        "      FieldInjection instance, Provider<String> stringProvider) {",
+        "    instance.string = stringProvider.get();",
+        "  }",
+        "",
+        "  public static void injectLazyString(",
+        "      FieldInjection instance, Provider<String> lazyStringProvider) {",
+        "    instance.lazyString = DoubleCheckLazy.create(lazyStringProvider);",
+        "  }",
+        "",
+        "  public static void injectStringProvider(",
+        "      FieldInjection instance, Provider<String> stringProvider) {",
+        "    instance.stringProvider = stringProvider;",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test public void methodInjection() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.MethodInjection",
+        "package test;",
+        "",
+        "import dagger.Lazy;",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "class MethodInjection {",
+        "  @Inject void noArgs() {}",
+        "  @Inject void oneArg(String string) {}",
+        "  @Inject void manyArgs(",
+        "      String string, Lazy<String> lazyString, Provider<String> stringProvider) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.MethodInjection_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.DoubleCheckLazy;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class MethodInjection_MembersInjector",
+        "     implements MembersInjector<MethodInjection> {",
+        "",
+        "  private final Provider<String> stringProvider;",
+        "",
+        "  public MethodInjection_MembersInjector(Provider<String> stringProvider) {",
+        "    assert stringProvider != null;",
+        "    this.stringProvider = stringProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(MethodInjection instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.noArgs();",
+        "    instance.oneArg(stringProvider.get());",
+        "    instance.manyArgs(stringProvider.get(), DoubleCheckLazy.create(stringProvider),",
+        "        stringProvider);",
+        "  }",
+        "",
+        "  public static MembersInjector<MethodInjection> create(",
+        "      Provider<String> stringProvider) {",
+        "    return new MethodInjection_MembersInjector(stringProvider);",
+        "  }",
+        "",
+        "  public static void injectNoArgs(MethodInjection instance) {",
+        "    instance.noArgs();",
+        "  }",
+        "",
+        "  public static void injectOneArg(",
+        "      MethodInjection instance, Provider<String> stringProvider) {",
+        "    instance.oneArg(stringProvider.get());",
+        "  }",
+        "",
+        "  public static void injectManyArgs(",
+        "      MethodInjection instance,",
+        "      Provider<String> stringProvider,",
+        "      Provider<String> lazyStringProvider,",
+        "      Provider<String> stringProvider2) {",
+        "    instance.manyArgs(",
+        "        stringProvider.get(),",
+        "        DoubleCheckLazy.create(lazyStringProvider),",
+        "        stringProvider2);",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test
+  public void mixedMemberInjection() {
+    JavaFileObject file = JavaFileObjects.forSourceLines(
+        "test.MixedMemberInjection",
+        "package test;",
+        "",
+        "import dagger.Lazy;",
+        "import javax.inject.Inject;",
+        "import javax.inject.Provider;",
+        "",
+        "class MixedMemberInjection {",
+        "  @Inject String string;",
+        "  @Inject void setString(String s) {}",
+        "  @Inject Object object;",
+        "  @Inject void setObject(Object o) {}",
+        "}");
+    JavaFileObject expected = JavaFileObjects.forSourceLines(
+        "test.MixedMemberInjection_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class MixedMemberInjection_MembersInjector",
+        "    implements MembersInjector<MixedMemberInjection> {",
+        "",
+        "  private final Provider<String> stringAndSProvider;",
+        "  private final Provider<Object> objectAndOProvider;",
+        "",
+        "  public MixedMemberInjection_MembersInjector(",
+        "      Provider<String> stringAndSProvider,",
+        "      Provider<Object> objectAndOProvider) {",
+        "    assert stringAndSProvider != null;",
+        "    this.stringAndSProvider = stringAndSProvider;",
+        "    assert objectAndOProvider != null;",
+        "    this.objectAndOProvider = objectAndOProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(MixedMemberInjection instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.string = stringAndSProvider.get();",
+        "    instance.object = objectAndOProvider.get();",
+        "    instance.setString(stringAndSProvider.get());",
+        "    instance.setObject(objectAndOProvider.get());",
+        "  }",
+        "",
+        "  public static MembersInjector<MixedMemberInjection> create(",
+        "      Provider<String> stringAndSProvider,",
+        "      Provider<Object> objectAndOProvider) {",
+        "    return new MixedMemberInjection_MembersInjector(",
+        "        stringAndSProvider, objectAndOProvider);",
+        "  }",
+        "  public static void injectString(",
+        "      MixedMemberInjection instance, Provider<String> stringProvider) {",
+        "    instance.string = stringProvider.get();",
+        "  }",
+        "",
+        "  public static void injectObject(",
+        "      MixedMemberInjection instance, Provider<Object> objectProvider) {",
+        "    instance.object = objectProvider.get();",
+        "  }",
+        "",
+        "  public static void injectSetString(",
+        "      MixedMemberInjection instance, Provider<String> sProvider) {",
+        "    instance.setString(sProvider.get());",
+        "  }",
+        "",
+        "  public static void injectSetObject(",
+        "      MixedMemberInjection instance, Provider<Object> oProvider) {",
+        "    instance.setObject(oProvider.get());",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expected);
+  }
+
+  @Test public void injectConstructorAndMembersInjection() {
+    JavaFileObject file = JavaFileObjects.forSourceLines("test.AllInjections",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class AllInjections {",
+        "  @Inject String s;",
+        "  @Inject AllInjections(String s) {}",
+        "  @Inject void s(String s) {}",
+        "}");
+    JavaFileObject expectedMembersInjector = JavaFileObjects.forSourceLines(
+        "test.AllInjections_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class AllInjections_MembersInjector ",
+        "    implements MembersInjector<AllInjections> {",
+        "",
+        "  private final Provider<String> sProvider;",
+        "",
+        "  public AllInjections_MembersInjector(Provider<String> sProvider) {",
+        "    assert sProvider != null;",
+        "    this.sProvider = sProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(AllInjections instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.s = sProvider.get();",
+        "    instance.s(sProvider.get());",
+        "  }",
+        "",
+        "  public static MembersInjector<AllInjections> create(Provider<String> sProvider) {",
+        "      return new AllInjections_MembersInjector(sProvider);",
+        "  }",
+        "",
+        "  public static void injectS(AllInjections instance, Provider<String> sProvider) {",
+        "    instance.s = sProvider.get();",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expectedMembersInjector);
+  }
+
+  @Test public void supertypeMembersInjection() {
+    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
+        "package test;",
+        "",
+        "class A {}");
+    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class B extends A {",
+        "  @Inject String s;",
+        "}");
+    JavaFileObject expectedMembersInjector = JavaFileObjects.forSourceLines(
+        "test.AllInjections_MembersInjector",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class B_MembersInjector implements MembersInjector<B> {",
+        "  private final Provider<String> sProvider;",
+        "",
+        "  public B_MembersInjector(Provider<String> sProvider) {",
+        "    assert sProvider != null;",
+        "    this.sProvider = sProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public void injectMembers(B instance) {",
+        "    if (instance == null) {",
+        "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+        "    }",
+        "    instance.s = sProvider.get();",
+        "  }",
+        "",
+        "  public static MembersInjector<B> create(Provider<String> sProvider) {",
+        "      return new B_MembersInjector(sProvider);",
+        "  }",
+        "  public static void injectS(B instance, Provider<String> sProvider) {",
+        "    instance.s = sProvider.get();",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(aFile, bFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expectedMembersInjector);
+  }
+
+  @Test
+  public void simpleComponentWithNesting() {
+    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines(
+          "test.OuterType",
+          "package test;",
+          "",
+          "import dagger.Component;",
+          "import javax.inject.Inject;",
+          "",
+          "final class OuterType {",
+          "  static class A {",
+          "    @Inject A() {}",
+          "  }",
+          "  static class B {",
+          "    @Inject A a;",
+          "  }",
+          "  @Component interface SimpleComponent {",
+          "    A a();",
+          "    void inject(B b);",
+          "  }",
+          "}");
+    JavaFileObject bMembersInjector = JavaFileObjects.forSourceLines(
+          "test.OuterType$B_MembersInjector",
+          "package test;",
+          "",
+          "import dagger.MembersInjector;",
+          "import javax.annotation.Generated;",
+          "import javax.inject.Provider;",
+          "import test.OuterType.A;",
+          "import test.OuterType.B;",
+          "",
+          "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+          "public final class OuterType$B_MembersInjector implements MembersInjector<B> {",
+          "  private final Provider<A> aProvider;",
+          "",
+          "  public OuterType$B_MembersInjector(Provider<A> aProvider) {",
+          "    assert aProvider != null;",
+          "    this.aProvider = aProvider;",
+          "  }",
+          "",
+          "  @Override",
+          "  public void injectMembers(B instance) {",
+          "    if (instance == null) {",
+          "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+          "    }",
+          "    instance.a = aProvider.get();",
+          "  }",
+          "",
+          "  public static MembersInjector<B> create(Provider<A> aProvider) {",
+          "    return new OuterType$B_MembersInjector(aProvider);",
+          "  }",
+          "",
+          "  public static void injectA(B instance, Provider<A> aProvider) {",
+          "    instance.a = aProvider.get();",
+          "  }",
+          "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(nestedTypesFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(bMembersInjector);
+  }
+
+  @Test
+  public void componentWithNestingAndGeneratedType() {
+    JavaFileObject nestedTypesFile =
+        JavaFileObjects.forSourceLines(
+            "test.OuterType",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "import javax.inject.Inject;",
+            "",
+            "final class OuterType {",
+            "  @Inject GeneratedType generated;",
+            "  static class A {",
+            "    @Inject A() {}",
+            "  }",
+            "  static class B {",
+            "    @Inject A a;",
+            "  }",
+            "  @Component interface SimpleComponent {",
+            "    A a();",
+            "    void inject(B b);",
+            "  }",
+            "}");
+    JavaFileObject bMembersInjector =
+        JavaFileObjects.forSourceLines(
+            "test.OuterType$B_MembersInjector",
+            "package test;",
+            "",
+            "import dagger.MembersInjector;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "import test.OuterType.A;",
+            "import test.OuterType.B;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class OuterType$B_MembersInjector implements MembersInjector<B> {",
+            "  private final Provider<A> aProvider;",
+            "",
+            "  public OuterType$B_MembersInjector(Provider<A> aProvider) {",
+            "    assert aProvider != null;",
+            "    this.aProvider = aProvider;",
+            "  }",
+            "",
+            "  @Override",
+            "  public void injectMembers(B instance) {",
+            "    if (instance == null) {",
+            "      throw new NullPointerException(\"Cannot inject members into a null reference\");",
+            "    }",
+            "    instance.a = aProvider.get();",
+            "  }",
+            "",
+            "  public static MembersInjector<B> create(Provider<A> aProvider) {",
+            "    return new OuterType$B_MembersInjector(aProvider);",
+            "  }",
+            "",
+            "  public static void injectA(B instance, Provider<A> aProvider) {",
+            "    instance.a = aProvider.get();",
+            "  }",
+            "}");
+    assertAbout(javaSource())
+        .that(nestedTypesFile)
+        .processedWith(
+            new ComponentProcessor(),
+            new AbstractProcessor() {
+              private boolean done;
+
+              @Override
+              public Set<String> getSupportedAnnotationTypes() {
+                return ImmutableSet.of("*");
+              }
+
+              @Override
+              public boolean process(
+                  Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+                if (!done) {
+                  done = true;
+                  try (Writer writer =
+                          processingEnv
+                              .getFiler()
+                              .createSourceFile("test.GeneratedType")
+                              .openWriter()) {
+                    writer.write(
+                        Joiner.on('\n')
+                            .join(
+                                "package test;",
+                                "",
+                                "import javax.inject.Inject;",
+                                "",
+                                "class GeneratedType {",
+                                "  @Inject GeneratedType() {}",
+                                "}"));
+                  } catch (IOException e) {
+                    throw new RuntimeException(e);
+                  }
+                }
+                return false;
+              }
+            })
+        .compilesWithoutError()
+        .and()
+        .generatesSources(bMembersInjector);
+  }
+
+  @Test
+  public void lowerCaseNamedMembersInjector_forLowerCaseType() {
+    JavaFileObject foo =
+        JavaFileObjects.forSourceLines(
+            "test.foo",
+            "package test;",
+            "",
+            "import javax.inject.Inject;",
+            "",
+            "class foo {",
+            "  @Inject String string;",
+            "}");
+    JavaFileObject fooModule =
+        JavaFileObjects.forSourceLines(
+            "test.fooModule",
+            "package test;",
+            "",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "",
+            "@Module",
+            "class fooModule {",
+            "  @Provides String string() { return \"foo\"; }",
+            "}");
+    JavaFileObject fooComponent =
+        JavaFileObjects.forSourceLines(
+            "test.fooComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component(modules = fooModule.class)",
+            "interface fooComponent {",
+            "  void inject(foo target);",
+            "}");
+
+    assertAbout(javaSources())
+        .that(ImmutableList.of(foo, fooModule, fooComponent))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesFileNamed(CLASS_OUTPUT, "test", "foo_MembersInjector.class");
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MethodSignatureFormatterTest.java b/compiler/src/test/java/dagger/internal/codegen/MethodSignatureFormatterTest.java
new file mode 100644
index 0000000..45791c7
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MethodSignatureFormatterTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.testing.compile.CompilationRule;
+import dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.InnerClass;
+import javax.inject.Singleton;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+@RunWith(JUnit4.class)
+public class MethodSignatureFormatterTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  static class OuterClass {
+    @interface Foo {
+       Class<?> bar();
+    }
+
+    static class InnerClass {
+      @Foo(bar = String.class)
+      @Singleton
+      String foo(@SuppressWarnings("unused") int a, ImmutableList<Boolean> blah) { return "foo"; }
+    }
+  }
+
+  @Test public void methodSignatureTest() {
+    Elements elements = compilationRule.getElements();
+    TypeElement inner = elements.getTypeElement(InnerClass.class.getCanonicalName());
+    ExecutableElement method = Iterables.getOnlyElement(methodsIn(inner.getEnclosedElements()));
+    String formatted = new MethodSignatureFormatter(compilationRule.getTypes()).format(method);
+    // This is gross, but it turns out that annotation order is not guaranteed when getting
+    // all the AnnotationMirrors from an Element, so I have to test this chopped-up to make it
+    // less brittle.
+    assertThat(formatted).contains("@Singleton");
+    assertThat(formatted).doesNotContain("@javax.inject.Singleton"); // maybe more importantly
+    assertThat(formatted)
+        .contains("@dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.Foo"
+            + "(bar=String.class)");
+    assertThat(formatted).contains(" String "); // return type compressed
+    assertThat(formatted).contains("int, ImmutableList<Boolean>)"); // parameters compressed.
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MissingBindingSuggestionsTest.java b/compiler/src/test/java/dagger/internal/codegen/MissingBindingSuggestionsTest.java
new file mode 100644
index 0000000..03ec35d
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MissingBindingSuggestionsTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class MissingBindingSuggestionsTest {
+  private static JavaFileObject injectable(String className, String constructorParams) {
+    return JavaFileObjects.forSourceLines("test." + className,
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class " + className +" {",
+        "  @Inject " + className + "(" + constructorParams + ") {}",
+        "}");
+  }
+
+  private static JavaFileObject emptyInterface(String interfaceName) {
+    return JavaFileObjects.forSourceLines("test." + interfaceName,
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "interface " + interfaceName +" {}");
+  }
+
+  @Test public void suggestsBindingInSeparateComponent() {
+    JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface FooComponent {",
+        "  Foo getFoo();",
+        "}");
+    JavaFileObject barModule = JavaFileObjects.forSourceLines("test.BarModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class BarModule {",
+        "  @Provides Bar provideBar() {return null;}",
+        "}");
+    JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = {BarModule.class})",
+        "interface BarComponent {",
+        "  Bar getBar();",
+        "}");
+    JavaFileObject foo = injectable("Foo", "Bar bar");
+    JavaFileObject bar = emptyInterface("Bar");
+
+    JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TopComponent {",
+        "  FooComponent getFoo();",
+        "  BarComponent getBar(BarModule barModule);",
+        "}");
+
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            fooComponent, barComponent, topComponent, foo, bar, barModule))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("A binding with matching key exists in component: test.BarComponent");
+  }
+
+  @Test public void suggestsBindingInNestedSubcomponent() {
+    JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface FooComponent {",
+        "  Foo getFoo();",
+        "}");
+    JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent()",
+        "interface BarComponent {",
+        "  BazComponent getBaz();",
+        "}");
+    JavaFileObject bazModule = JavaFileObjects.forSourceLines("test.BazModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "import javax.inject.Inject;",
+        "",
+        "@dagger.Module",
+        "final class BazModule {",
+        "  @Provides Baz provideBaz() {return null;}",
+        "}");
+    JavaFileObject bazComponent = JavaFileObjects.forSourceLines("test.BazComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = {BazModule.class})",
+        "interface BazComponent {",
+        "  Baz getBaz();",
+        "}");
+    JavaFileObject foo = injectable("Foo", "Baz baz");
+    JavaFileObject baz = emptyInterface("Baz");
+
+    JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TopComponent {",
+        "  FooComponent getFoo();",
+        "  BarComponent getBar();",
+        "}");
+
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            fooComponent, barComponent, bazComponent, topComponent, foo, baz, bazModule))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("A binding with matching key exists in component: test.BazComponent");
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ModuleFactoryGeneratorTest.java b/compiler/src/test/java/dagger/internal/codegen/ModuleFactoryGeneratorTest.java
new file mode 100644
index 0000000..72248e0
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ModuleFactoryGeneratorTest.java
@@ -0,0 +1,1070 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import dagger.internal.codegen.writer.StringLiteral;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_MUST_RETURN_A_VALUE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_IN_MODULE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_PRIVATE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_SET_VALUES_RAW_SET;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_TYPE_PARAMETER;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_SAME_NAME;
+import static dagger.internal.codegen.ErrorMessages.MODULES_WITH_TYPE_PARAMS_MUST_BE_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_METHOD_RETURN_TYPE;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_METHOD_SET_VALUES_RETURN_SET;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS;
+
+@RunWith(JUnit4.class)
+public class ModuleFactoryGeneratorTest {
+
+  private final JavaFileObject NULLABLE = JavaFileObjects.forSourceLines("test.Nullable",
+      "package test;",
+      "public @interface Nullable {}");
+
+  private static final StringLiteral NPE_LITERAL =
+      StringLiteral.forValue(ErrorMessages.CANNOT_RETURN_NULL_FROM_NON_NULLABLE_PROVIDES_METHOD);
+
+  // TODO(gak): add tests for invalid combinations of scope and qualifier annotations like we have
+  // for @Inject
+
+  private String formatErrorMessage(String msg) {
+    return String.format(msg, "Provides");
+  }
+
+  private String formatModuleErrorMessage(String msg) {
+    return String.format(msg, "Provides", "Module");
+  }
+
+  @Test public void providesMethodNotInModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Provides;",
+        "",
+        "final class TestModule {",
+        "  @Provides String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatModuleErrorMessage(BINDING_METHOD_NOT_IN_MODULE));
+  }
+
+  @Test public void providesMethodAbstract() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "abstract class TestModule {",
+        "  @Provides abstract String provideString();",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_ABSTRACT));
+  }
+
+  @Test public void providesMethodPrivate() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides private String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_PRIVATE));
+  }
+
+  @Test public void providesMethodReturnVoid() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides void provideNothing() {}",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_MUST_RETURN_A_VALUE));
+  }
+
+  @Test public void providesMethodWithTypeParameter() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides <T> String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_TYPE_PARAMETER));
+  }
+
+  @Test public void providesMethodSetValuesWildcard() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET_VALUES;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET_VALUES) Set<?> provideWildcard() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PROVIDES_METHOD_RETURN_TYPE);
+  }
+
+  @Test public void providesMethodSetValuesRawSet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET_VALUES;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET_VALUES) Set provideSomething() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_SET_VALUES_RAW_SET));
+  }
+
+  @Test public void providesMethodSetValuesNotASet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET_VALUES;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "import java.util.List;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET_VALUES) List<String> provideStrings() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PROVIDES_METHOD_SET_VALUES_RETURN_SET);
+  }
+
+  @Test public void modulesWithTypeParamsMustBeAbstract() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule<A> {}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MODULES_WITH_TYPE_PARAMS_MUST_BE_ABSTRACT);
+  }
+
+  @Test public void provideOverriddenByNoProvide() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class Parent {",
+        "  @Provides String foo() { return null; }",
+        "}");
+    JavaFileObject child = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "class Child extends Parent{",
+        "  String foo() { return null; }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(parent, child))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(ErrorMessages.METHOD_OVERRIDES_PROVIDES_METHOD,
+            "Provides", "@Provides String test.Parent.foo()"));
+  }
+
+  @Test public void provideOverriddenByProvide() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class Parent {",
+        "  @Provides String foo() { return null; }",
+        "}");
+    JavaFileObject child = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class Child extends Parent{",
+        "  @Provides String foo() { return null; }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(parent, child))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(ErrorMessages.PROVIDES_METHOD_OVERRIDES_ANOTHER,
+            "Provides", "@Provides String test.Parent.foo()"));
+  }
+
+  @Test public void providesOverridesNonProvides() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "class Parent {",
+        "  String foo() { return null; }",
+        "}");
+    JavaFileObject child = JavaFileObjects.forSourceLines("test.Child",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class Child extends Parent{",
+        "  @Provides String foo() { return null; }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(parent, child))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(ErrorMessages.PROVIDES_METHOD_OVERRIDES_ANOTHER,
+            "Provides", "String test.Parent.foo()"));
+  }
+
+  @Test public void validatesIncludedModules() {
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = Void.class)",
+        "class TestModule {}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(module))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(
+                ErrorMessages.REFERENCED_MODULE_NOT_ANNOTATED, "java.lang.Void", "@Module"));
+  }
+
+  @Test public void referencedModulesMustNotBeAbstract() {
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.Parent",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = AbstractModule.class)",
+        "class TestModule {}");
+    JavaFileObject abstractModule = JavaFileObjects.forSourceLines("test.AbstractModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "abstract class AbstractModule {}");
+    assertAbout(javaSources()).that(ImmutableList.of(module, abstractModule))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(ErrorMessages.REFERENCED_MODULES_MUST_NOT_BE_ABSTRACT,
+            "test.AbstractModule"));
+  }
+
+  @Test public void singleProvidesMethodNoArgs() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("TestModule_ProvideStringFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideStringFactory implements Factory<String> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideStringFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override public String get() {",
+        "    String provided = module.provideString();",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static Factory<String> create(TestModule module) {",
+        "    return new TestModule_ProvideStringFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  @Test public void singleProvidesMethodNoArgs_disableNullable() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("TestModule_ProvideStringFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideStringFactory implements Factory<String> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideStringFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override public String get() {",
+        "    return module.provideString();",
+        "  }",
+        "",
+        "  public static Factory<String> create(TestModule module) {",
+        "    return new TestModule_ProvideStringFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  @Test public void nullableProvides() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides @Nullable String provideString() { return null; }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("TestModule_ProvideStringFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideStringFactory implements Factory<String> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideStringFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override",
+        "  @Nullable",
+        "  public String get() {",
+        "    return module.provideString();",
+        "  }",
+        "",
+        "  public static Factory<String> create(TestModule module) {",
+        "    return new TestModule_ProvideStringFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, NULLABLE))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  private static final JavaFileObject QUALIFIER_A =
+      JavaFileObjects.forSourceLines("test.QualifierA",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierA {}");
+  private static final JavaFileObject QUALIFIER_B =
+      JavaFileObjects.forSourceLines("test.QualifierB",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierB {}");
+
+  @Test public void multipleProvidesMethods() {
+    JavaFileObject classXFile = JavaFileObjects.forSourceLines("test.X",
+        "package test;",
+        "",
+        "import javax.inject.Inject;",
+        "",
+        "class X {",
+        "  @Inject public String s;",
+        "}");
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "import java.util.Arrays;",
+        "import java.util.List;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides List<Object> provideObjects(",
+        "      @QualifierA Object a, @QualifierB Object b, MembersInjector<X> x) {",
+        "    return Arrays.asList(a, b);",
+        "  }",
+        "",
+        "  @Provides @QualifierA Object provideAObject() {",
+        "    return new Object();",
+        "  }",
+        "",
+        "  @Provides @QualifierB Object provideBObject() {",
+        "    return new Object();",
+        "  }",
+        "}");
+    JavaFileObject listFactoryFile = JavaFileObjects.forSourceLines(
+        "TestModule_ProvideObjectsFactory",
+        "package test;",
+        "",
+        "import dagger.MembersInjector;",
+        "import dagger.internal.Factory;",
+        "import java.util.List;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideObjectsFactory implements Factory<List<Object>> {",
+        "  private final TestModule module;",
+        "  private final Provider<Object> aProvider;",
+        "  private final Provider<Object> bProvider;",
+        "  private final MembersInjector<X> xMembersInjector;",
+        "",
+        "  public TestModule_ProvideObjectsFactory(",
+        "      TestModule module,",
+        "      Provider<Object> aProvider,",
+        "      Provider<Object> bProvider,",
+        "      MembersInjector<X> xMembersInjector) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "    assert aProvider != null;",
+        "    this.aProvider = aProvider;",
+        "    assert bProvider != null;",
+        "    this.bProvider = bProvider;",
+        "    assert xMembersInjector != null;",
+        "    this.xMembersInjector = xMembersInjector;",
+        "  }",
+        "",
+        "  @Override public List<Object> get() {",
+        "    List<Object> provided =",
+        "        module.provideObjects(aProvider.get(), bProvider.get(), xMembersInjector);",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static Factory<List<Object>> create(",
+        "      TestModule module,",
+        "      Provider<Object> aProvider,",
+        "      Provider<Object> bProvider,",
+        "      MembersInjector<X> xMembersInjector) {",
+        "    return new TestModule_ProvideObjectsFactory(",
+        "        module, aProvider, bProvider, xMembersInjector);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(
+            ImmutableList.of(classXFile, moduleFile, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(listFactoryFile);
+  }
+
+  @Test public void providesSetElement() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET;",
+        "",
+        "import java.util.logging.Logger;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET) String provideString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("TestModule_ProvideStringFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.Collections;",
+        "import java.util.Set;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideStringFactory implements Factory<Set<String>> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideStringFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override public Set<String> get() {",
+        "    return Collections.<String>singleton(module.provideString());",
+        "  }",
+        "",
+        "  public static Factory<Set<String>> create(TestModule module) {",
+        "    return new TestModule_ProvideStringFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  @Test public void providesSetElementWildcard() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET;",
+        "",
+        "import java.util.logging.Logger;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.ArrayList;",
+        "import java.util.List;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET) List<List<?>> provideWildcardList() {",
+        "    return new ArrayList<>();",
+        "  }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines(
+        "TestModule_ProvideWildcardListFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.Collections;",
+        "import java.util.List;",
+        "import java.util.Set;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideWildcardListFactory implements "
+            + "Factory<Set<List<List<?>>>> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideWildcardListFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override public Set<List<List<?>>> get() {",
+        "    return Collections.<List<List<?>>>singleton(module.provideWildcardList());",
+        "  }",
+        "",
+        "  public static Factory<Set<List<List<?>>>> create(TestModule module) {",
+        "    return new TestModule_ProvideWildcardListFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  @Test public void providesSetValues() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.Provides.Type.SET_VALUES;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.Set;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides(type = SET_VALUES) Set<String> provideStrings() {",
+        "    return null;",
+        "  }",
+        "}");
+    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("TestModule_ProvideStringsFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.Set;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class TestModule_ProvideStringsFactory implements Factory<Set<String>> {",
+        "  private final TestModule module;",
+        "",
+        "  public TestModule_ProvideStringsFactory(TestModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override public Set<String> get() {",
+        "    Set<String> provided = module.provideStrings();",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static Factory<Set<String>> create(TestModule module) {",
+        "    return new TestModule_ProvideStringsFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(factoryFile);
+  }
+
+  @Test public void multipleProvidesMethodsWithSameName() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides Object provide(int i) {",
+        "    return i;",
+        "  }",
+        "",
+        "  @Provides String provide() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+    .withErrorContaining(formatErrorMessage(BINDING_METHOD_WITH_SAME_NAME)).in(moduleFile).onLine(8)
+        .and().withErrorContaining(formatErrorMessage(BINDING_METHOD_WITH_SAME_NAME))
+        .in(moduleFile).onLine(12);
+  }
+
+  @Test
+  public void providedTypes() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.io.Closeable;",
+        "import java.util.Set;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides String string() {",
+        "    return null;",
+        "  }",
+        "",
+        "  @Provides Set<String> strings() {",
+        "    return null;",
+        "  }",
+        "",
+        "  @Provides Set<? extends Closeable> closeables() {",
+        "    return null;",
+        "  }",
+        "",
+        "  @Provides String[] stringArray() {",
+        "    return null;",
+        "  }",
+        "",
+        "  @Provides int integer() {",
+        "    return 0;",
+        "  }",
+        "",
+        "  @Provides int[] integers() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test
+  public void privateModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "final class Enclosing {",
+        "  @Module private static final class PrivateModule {",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("Modules cannot be private.")
+        .in(moduleFile).onLine(6);
+  }
+
+  @Test
+  public void enclosedInPrivateModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "final class Enclosing {",
+        "  private static final class PrivateEnclosing {",
+        "    @Module static final class TestModule {",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("Modules cannot be enclosed in private types.")
+        .in(moduleFile).onLine(7);
+  }
+
+  @Test
+  public void publicModuleNonPublicIncludes() {
+    JavaFileObject publicModuleFile = JavaFileObjects.forSourceLines("test.PublicModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module(includes = {",
+        "    NonPublicModule1.class, OtherPublicModule.class, NonPublicModule2.class",
+        "})",
+        "public final class PublicModule {",
+        "}");
+    JavaFileObject nonPublicModule1File = JavaFileObjects.forSourceLines("test.NonPublicModule1",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "final class NonPublicModule1 {",
+        "}");
+    JavaFileObject nonPublicModule2File = JavaFileObjects.forSourceLines("test.NonPublicModule2",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "final class NonPublicModule2 {",
+        "}");
+    JavaFileObject otherPublicModuleFile = JavaFileObjects.forSourceLines("test.OtherPublicModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "public final class OtherPublicModule {",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            publicModuleFile, nonPublicModule1File, nonPublicModule2File, otherPublicModuleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("This module is public, but it includes non-public "
+            + "(or effectively non-public) modules. "
+            + "Either reduce the visibility of this module or make "
+            + "test.NonPublicModule1 and test.NonPublicModule2 public.")
+        .in(publicModuleFile).onLine(8);
+  }
+
+  @Test
+  public void genericSubclassedModule() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines("test.ParentModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import java.util.List;",
+        "import java.util.ArrayList;",
+        "",
+        "@Module",
+        "abstract class ParentModule<A extends CharSequence,",
+        "                            B,",
+        "                            C extends Number & Comparable<C>> {",
+        "  @Provides List<B> provideListB(B b) {",
+        "    List<B> list = new ArrayList<B>();",
+        "    list.add(b);",
+        "    return list;",
+        "  }",
+        "}");
+    JavaFileObject numberChild = JavaFileObjects.forSourceLines("test.ChildNumberModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class ChildNumberModule extends ParentModule<String, Number, Double> {",
+        "  @Provides Number provideNumber() { return 1; }",
+        "}");
+    JavaFileObject integerChild = JavaFileObjects.forSourceLines("test.ChildIntegerModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "class ChildIntegerModule extends ParentModule<StringBuilder, Integer, Float> {",
+        "  @Provides Integer provideInteger() { return 2; }",
+        "}");
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.C",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import java.util.List;",
+        "",
+        "@Component(modules={ChildNumberModule.class, ChildIntegerModule.class})",
+        "interface C {",
+        "  List<Number> numberList();",
+        "  List<Integer> integerList();",
+        "}");
+    JavaFileObject listBFactory = JavaFileObjects.forSourceLines(
+        "test.ParentModule_ProvidesListBFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import java.util.List;",
+        "import javax.annotation.Generated;",
+        "import javax.inject.Provider;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class ParentModule_ProvideListBFactory<A extends CharSequence,",
+        "    B, C extends Number & Comparable<C>> implements Factory<List<B>> {",
+        "  private final ParentModule<A, B, C> module;",
+        "  private final Provider<B> bProvider;",
+        "",
+        "  public ParentModule_ProvideListBFactory(",
+        "        ParentModule<A, B, C> module, Provider<B> bProvider) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "    assert bProvider != null;",
+        "    this.bProvider = bProvider;",
+        "  }",
+        "",
+        "  @Override",
+        "  public List<B> get() {  ",
+        "    List<B> provided = module.provideListB(bProvider.get());",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
+        "      Factory<List<B>> create(ParentModule<A, B, C> module, Provider<B> bProvider) {",
+        "    return new ParentModule_ProvideListBFactory<A, B, C>(module, bProvider);",
+        "  }",
+        "}");
+    JavaFileObject numberFactory = JavaFileObjects.forSourceLines(
+        "test.ChildNumberModule_ProvideNumberFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class ChildNumberModule_ProvideNumberFactory implements Factory<Number> {",
+        "  private final ChildNumberModule module;",
+        "",
+        "  public ChildNumberModule_ProvideNumberFactory(ChildNumberModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override",
+        "  public Number get() {  ",
+        "    Number provided = module.provideNumber();",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static Factory<Number> create(ChildNumberModule module) {",
+        "    return new ChildNumberModule_ProvideNumberFactory(module);",
+        "  }",
+        "}");
+    JavaFileObject integerFactory = JavaFileObjects.forSourceLines(
+        "test.ChildIntegerModule_ProvideIntegerFactory",
+        "package test;",
+        "",
+        "import dagger.internal.Factory;",
+        "import javax.annotation.Generated;",
+        "",
+        "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+        "public final class ChildIntegerModule_ProvideIntegerFactory",
+        "    implements Factory<Integer> {",
+        "  private final ChildIntegerModule module;",
+        "",
+        "  public ChildIntegerModule_ProvideIntegerFactory(ChildIntegerModule module) {",
+        "    assert module != null;",
+        "    this.module = module;",
+        "  }",
+        "",
+        "  @Override",
+        "  public Integer get() {  ",
+        "    Integer provided = module.provideInteger();",
+        "    if (provided == null) {",
+        "      throw new NullPointerException(" + NPE_LITERAL + ");",
+        "    }",
+        "    return provided;",
+        "  }",
+        "",
+        "  public static Factory<Integer> create(ChildIntegerModule module) {",
+        "    return new ChildIntegerModule_ProvideIntegerFactory(module);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(parent, numberChild, integerChild, component))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(listBFactory, numberFactory, integerFactory);
+  }
+
+  @Test public void providesMethodMultipleQualifiers() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "import javax.annotation.Nullable;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides @QualifierA @QualifierB String provideString() {",
+        "    return \"foo\";",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/MultipleRequestTest.java b/compiler/src/test/java/dagger/internal/codegen/MultipleRequestTest.java
new file mode 100644
index 0000000..27e720d
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/MultipleRequestTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class MultipleRequestTest {
+  private static final JavaFileObject DEP_FILE = JavaFileObjects.forSourceLines("test.Dep",
+      "package test;",
+      "",
+      "import javax.inject.Inject;",
+      "",
+      "class Dep {",
+      "  @Inject Dep() {}",
+      "}");
+
+  @Test public void multipleRequests_constructor() {
+    assert_().about(javaSources())
+        .that(ImmutableList.of(
+            DEP_FILE,
+            JavaFileObjects.forSourceLines("test.ConstructorInjectsMultiple",
+                "package test;",
+                "",
+                "import javax.inject.Inject;",
+                "",
+                "class ConstructorInjectsMultiple {",
+                "  @Inject ConstructorInjectsMultiple(Dep d1, Dep d2) {}",
+                "}"),
+            JavaFileObjects.forSourceLines("test.SimpleComponent",
+                "package test;",
+                "",
+                "import dagger.Component;",
+                "",
+                "@Component",
+                "interface SimpleComponent {",
+                "  ConstructorInjectsMultiple get();",
+                "}")))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void multipleRequests_field() {
+    assert_().about(javaSources())
+        .that(ImmutableList.of(
+            DEP_FILE,
+            JavaFileObjects.forSourceLines("test.FieldInjectsMultiple",
+                "package test;",
+                "",
+                "import javax.inject.Inject;",
+                "",
+                "class FieldInjectsMultiple {",
+                "  @Inject Dep d1;",
+                "  @Inject Dep d2;",
+                "  @Inject FieldInjectsMultiple() {}",
+                "}"),
+            JavaFileObjects.forSourceLines("test.SimpleComponent",
+                "package test;",
+                "",
+                "import dagger.Component;",
+                "",
+                "@Component",
+                "interface SimpleComponent {",
+                "  FieldInjectsMultiple get();",
+                "}")))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void multipleRequests_providesMethod() {
+    assert_().about(javaSources())
+        .that(ImmutableList.of(
+            DEP_FILE,
+            JavaFileObjects.forSourceLines("test.FieldInjectsMultiple",
+                "package test;",
+                "",
+                "import dagger.Module;",
+                "import dagger.Provides;",
+                "",
+                "@Module",
+                "class SimpleModule {",
+                "  @Provides Object provide(Dep d1, Dep d2) {",
+                "    return null;",
+                "  }",
+                "}"),
+            JavaFileObjects.forSourceLines("test.SimpleComponent",
+                "package test;",
+                "",
+                "import dagger.Component;",
+                "",
+                "@Component(modules = SimpleModule.class)",
+                "interface SimpleComponent {",
+                "  Object get();",
+                "}")))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java b/compiler/src/test/java/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java
new file mode 100644
index 0000000..f9c2878
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.
+ */
+// TODO(beder): Merge the error-handling tests with the ModuleFactoryGeneratorTest.
+package dagger.internal.codegen;
+
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_ABSTRACT;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_MUST_RETURN_A_VALUE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_NOT_IN_MODULE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_PRIVATE;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_SET_VALUES_RAW_SET;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_TYPE_PARAMETER;
+import static dagger.internal.codegen.ErrorMessages.BINDING_METHOD_WITH_SAME_NAME;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_RAW_FUTURE;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_RETURN_TYPE;
+import static dagger.internal.codegen.ErrorMessages.PRODUCES_METHOD_SET_VALUES_RETURN_SET;
+import static dagger.internal.codegen.ErrorMessages.PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS;
+
+@RunWith(JUnit4.class)
+public class ProducerModuleFactoryGeneratorTest {
+  private String formatErrorMessage(String msg) {
+    return String.format(msg, "Produces");
+  }
+
+  private String formatModuleErrorMessage(String msg) {
+    return String.format(msg, "Produces", "ProducerModule");
+  }
+
+  @Test public void producesMethodNotInModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.Produces;",
+        "",
+        "final class TestModule {",
+        "  @Produces String produceString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatModuleErrorMessage(BINDING_METHOD_NOT_IN_MODULE));
+  }
+
+  @Test public void producesMethodAbstract() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "abstract class TestModule {",
+        "  @Produces abstract String produceString();",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_ABSTRACT));
+  }
+
+  @Test public void producesMethodPrivate() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces private String produceString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_PRIVATE));
+  }
+
+  @Test public void producesMethodReturnVoid() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces void produceNothing() {}",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_MUST_RETURN_A_VALUE));
+  }
+
+  @Test public void producesMethodReturnRawFuture() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces ListenableFuture produceRaw() {}",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_RAW_FUTURE);
+  }
+
+  @Test public void producesMethodReturnWildcardFuture() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces ListenableFuture<?> produceRaw() {}",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_RETURN_TYPE);
+  }
+
+  @Test public void producesMethodWithTypeParameter() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces <T> String produceString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_TYPE_PARAMETER));
+  }
+
+  @Test public void producesMethodSetValuesWildcard() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) Set<?> produceWildcard() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_RETURN_TYPE);
+  }
+
+  @Test public void producesMethodSetValuesRawSet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) Set produceSomething() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_SET_VALUES_RAW_SET));
+  }
+
+  @Test public void producesMethodSetValuesNotASet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.List;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) List<String> produceStrings() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_SET_VALUES_RETURN_SET);
+  }
+
+  @Test public void producesMethodSetValuesWildcardInFuture() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) ListenableFuture<Set<?>> produceWildcard() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_RETURN_TYPE);
+  }
+
+  @Test public void producesMethodSetValuesFutureRawSet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.Set;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) ListenableFuture<Set> produceSomething() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(formatErrorMessage(BINDING_METHOD_SET_VALUES_RAW_SET));
+  }
+
+  @Test public void producesMethodSetValuesFutureNotASet() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import static dagger.producers.Produces.Type.SET_VALUES;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "import java.util.List;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces(type = SET_VALUES) ListenableFuture<List<String>> produceStrings() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PRODUCES_METHOD_SET_VALUES_RETURN_SET);
+  }
+
+  @Test public void multipleProducesMethodsWithSameName() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces Object produce(int i) {",
+        "    return i;",
+        "  }",
+        "",
+        "  @Produces String produce() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    String errorMessage = String.format(BINDING_METHOD_WITH_SAME_NAME, "Produces");
+    assertAbout(javaSource()).that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(errorMessage).in(moduleFile).onLine(8)
+        .and().withErrorContaining(errorMessage).in(moduleFile).onLine(12);
+  }
+
+  @Test
+  public void privateModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "final class Enclosing {",
+        "  @ProducerModule private static final class PrivateModule {",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("Modules cannot be private.")
+        .in(moduleFile).onLine(6);
+  }
+
+  @Test
+  public void enclosedInPrivateModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "final class Enclosing {",
+        "  private static final class PrivateEnclosing {",
+        "    @ProducerModule static final class TestModule {",
+        "    }",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("Modules cannot be enclosed in private types.")
+        .in(moduleFile).onLine(7);
+  }
+
+  @Test
+  public void includesNonModule() {
+    JavaFileObject xFile =
+        JavaFileObjects.forSourceLines("test.X", "package test;", "", "public final class X {}");
+    JavaFileObject moduleFile =
+        JavaFileObjects.forSourceLines(
+            "test.FooModule",
+            "package test;",
+            "",
+            "import dagger.producers.ProducerModule;",
+            "",
+            "@ProducerModule(includes = X.class)",
+            "public final class FooModule {",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(xFile, moduleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(
+                ErrorMessages.REFERENCED_MODULE_NOT_ANNOTATED,
+                "X",
+                "one of @Module, @ProducerModule"));
+  }
+
+  @Test
+  public void publicModuleNonPublicIncludes() {
+    JavaFileObject publicModuleFile = JavaFileObjects.forSourceLines("test.PublicModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "@ProducerModule(includes = {",
+        "    NonPublicModule1.class, OtherPublicModule.class, NonPublicModule2.class",
+        "})",
+        "public final class PublicModule {",
+        "}");
+    JavaFileObject nonPublicModule1File = JavaFileObjects.forSourceLines("test.NonPublicModule1",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "@ProducerModule",
+        "final class NonPublicModule1 {",
+        "}");
+    JavaFileObject nonPublicModule2File = JavaFileObjects.forSourceLines("test.NonPublicModule2",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "@ProducerModule",
+        "final class NonPublicModule2 {",
+        "}");
+    JavaFileObject otherPublicModuleFile = JavaFileObjects.forSourceLines("test.OtherPublicModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "",
+        "@ProducerModule",
+        "public final class OtherPublicModule {",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(
+            publicModuleFile, nonPublicModule1File, nonPublicModule2File, otherPublicModuleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("This module is public, but it includes non-public "
+            + "(or effectively non-public) modules. "
+            + "Either reduce the visibility of this module or make "
+            + "test.NonPublicModule1 and test.NonPublicModule2 public.")
+        .in(publicModuleFile).onLine(8);
+  }
+
+  @Test public void singleProducesMethodNoArgsFuture() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces ListenableFuture<String> produceString() {",
+        "    return null;",
+        "  }",
+        "}");
+    JavaFileObject factoryFile =
+        JavaFileObjects.forSourceLines(
+            "TestModule_ProduceStringFactory",
+            "package test;",
+            "",
+            "import com.google.common.util.concurrent.AsyncFunction;",
+            "import com.google.common.util.concurrent.Futures;",
+            "import com.google.common.util.concurrent.ListenableFuture;",
+            "import dagger.producers.internal.AbstractProducer;",
+            "import dagger.producers.monitoring.ProducerMonitor;",
+            "import dagger.producers.monitoring.ProducerToken;",
+            "import dagger.producers.monitoring.ProductionComponentMonitor;",
+            "import java.util.concurrent.Executor;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class TestModule_ProduceStringFactory extends AbstractProducer<String> {",
+            "  private final TestModule module;",
+            "  private final Executor executor;",
+            "  private final Provider<ProductionComponentMonitor> monitorProvider;",
+            "",
+            "  public TestModule_ProduceStringFactory(",
+            "      TestModule module,",
+            "      Executor executor,",
+            "      Provider<ProductionComponentMonitor> monitorProvider) {",
+            "    super(",
+            "        monitorProvider,",
+            "        ProducerToken.create(TestModule_ProduceStringFactory.class));",
+            "    assert module != null;",
+            "    this.module = module;",
+            "    assert executor != null;",
+            "    this.executor = executor;",
+            "    assert monitorProvider != null;",
+            "    this.monitorProvider = monitorProvider;",
+            "  }",
+            "",
+            "  @Override protected ListenableFuture<String> compute(",
+            "      final ProducerMonitor monitor) {",
+            "    return Futures.transform(",
+            "      Futures.<Void>immediateFuture(null),",
+            "      new AsyncFunction<Void, String>() {",
+            "        @Override public ListenableFuture<String> apply(Void ignoredVoidArg) {",
+            "          monitor.methodStarting();",
+            "          try {",
+            "            return module.produceString();",
+            "          } finally {",
+            "            monitor.methodFinished();",
+            "          }",
+            "        }",
+            "      }, executor);",
+            "  }",
+            "}");
+    assertAbout(javaSource())
+        .that(moduleFile)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(factoryFile);
+  }
+
+  private static final JavaFileObject QUALIFIER_A =
+      JavaFileObjects.forSourceLines("test.QualifierA",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierA {}");
+  private static final JavaFileObject QUALIFIER_B =
+      JavaFileObjects.forSourceLines("test.QualifierB",
+          "package test;",
+          "",
+          "import javax.inject.Qualifier;",
+          "",
+          "@Qualifier @interface QualifierB {}");
+
+  @Test public void producesMethodMultipleQualifiers() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "@ProducerModule",
+        "final class TestModule {",
+        "  @Produces @QualifierA @QualifierB abstract String produceString() {",
+        "    return \"\";",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, QUALIFIER_A, QUALIFIER_B))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(PROVIDES_OR_PRODUCES_METHOD_MULTIPLE_QUALIFIERS);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ProductionComponentProcessorTest.java b/compiler/src/test/java/dagger/internal/codegen/ProductionComponentProcessorTest.java
new file mode 100644
index 0000000..a8e39b2
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ProductionComponentProcessorTest.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+
+@RunWith(JUnit4.class)
+public class ProductionComponentProcessorTest {
+  @Test public void componentOnConcreteClass() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "@ProductionComponent",
+        "final class NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void componentOnEnum() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "@ProductionComponent",
+        "enum NotAComponent {",
+        "  INSTANCE",
+        "}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void componentOnAnnotation() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "@ProductionComponent",
+        "@interface NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void nonModuleModule() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
+        "package test;",
+        "",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "@ProductionComponent(modules = Object.class)",
+        "interface NotAComponent {}");
+    assertAbout(javaSource()).that(componentFile)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("is not annotated with @Module or @ProducerModule");
+  }
+
+  @Test public void simpleComponent() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "import dagger.producers.ProductionComponent;",
+        "import javax.inject.Inject;",
+        "",
+        "final class TestClass {",
+        "  static final class C {",
+        "    @Inject C() {}",
+        "  }",
+        "",
+        "  interface A {}",
+        "  interface B {}",
+        "",
+        "  @Module",
+        "  static final class BModule {",
+        "    @Provides B b(C c) {",
+        "      return null;",
+        "    }",
+        "  }",
+        "",
+        "  @ProducerModule",
+        "  static final class AModule {",
+        "    @Produces ListenableFuture<A> a(B b) {",
+        "      return null;",
+        "    }",
+        "  }",
+        "",
+        "  @ProductionComponent(modules = {AModule.class, BModule.class})",
+        "  interface SimpleComponent {",
+        "    ListenableFuture<A> a();",
+        "  }",
+        "}");
+    JavaFileObject generatedComponent =
+        JavaFileObjects.forSourceLines(
+            "test.DaggerTestClass_SimpleComponent",
+            "package test;",
+            "",
+            "import com.google.common.util.concurrent.ListenableFuture;",
+            "import dagger.internal.InstanceFactory;",
+            "import dagger.internal.SetFactory;",
+            "import dagger.producers.Producer;",
+            "import dagger.producers.internal.Producers;",
+            "import dagger.producers.monitoring.ProductionComponentMonitor;",
+            "import dagger.producers.monitoring.ProductionComponentMonitor.Factory;",
+            "import java.util.Set;",
+            "import java.util.concurrent.Executor;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "import test.TestClass.A;",
+            "import test.TestClass.AModule;",
+            "import test.TestClass.B;",
+            "import test.TestClass.BModule;",
+            "import test.TestClass.SimpleComponent;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class DaggerTestClass_SimpleComponent implements SimpleComponent {",
+            "  private Provider<SimpleComponent> simpleComponentProvider;",
+            "  private Provider<Set<Factory>> setOfFactoryContribution1Provider;",
+            "  private Provider<Set<Factory>> setOfFactoryProvider;",
+            "  private Provider<ProductionComponentMonitor> monitorProvider;",
+            "  private Provider<B> bProvider;",
+            "  private Producer<A> aProducer;",
+            "",
+            "  private DaggerTestClass_SimpleComponent(Builder builder) {",
+            "    assert builder != null;",
+            "    initialize(builder);",
+            "  }",
+            "",
+            "  public static Builder builder() {",
+            "    return new Builder();",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\")",
+            "  private void initialize(final Builder builder) {",
+            "    this.simpleComponentProvider = InstanceFactory.<SimpleComponent>create(this);",
+            "    this.setOfFactoryContribution1Provider =",
+            "        TestClass$SimpleComponent_MonitoringModule_DefaultSetOfFactoriesFactory",
+            "            .create();",
+            "    this.setOfFactoryProvider = SetFactory.create(setOfFactoryContribution1Provider);",
+            "    this.monitorProvider =",
+            "        TestClass$SimpleComponent_MonitoringModule_MonitorFactory.create(",
+            "            builder.testClass$SimpleComponent_MonitoringModule,",
+            "            simpleComponentProvider,",
+            "            setOfFactoryProvider);",
+            "    this.bProvider = TestClass$BModule_BFactory.create(",
+            "        builder.bModule, TestClass$C_Factory.create());",
+            "    this.aProducer = new TestClass$AModule_AFactory(",
+            "        builder.aModule,",
+            "        builder.executor,",
+            "        monitorProvider,",
+            "        Producers.producerFromProvider(bProvider));",
+            "  }",
+            "",
+            "  @Override",
+            "  public ListenableFuture<A> a() {",
+            "    return aProducer.get();",
+            "  }",
+            "",
+            "  public static final class Builder {",
+            "    private TestClass$SimpleComponent_MonitoringModule",
+            "        testClass$SimpleComponent_MonitoringModule;",
+            "    private BModule bModule;",
+            "    private AModule aModule;",
+            "    private Executor executor;",
+            "",
+            "    private Builder() {",
+            "    }",
+            "",
+            "    public SimpleComponent build() {",
+            "      if (testClass$SimpleComponent_MonitoringModule == null) {",
+            "        this.testClass$SimpleComponent_MonitoringModule =",
+            "            new TestClass$SimpleComponent_MonitoringModule();",
+            "      }",
+            "      if (bModule == null) {",
+            "        this.bModule = new BModule();",
+            "      }",
+            "      if (aModule == null) {",
+            "        this.aModule = new AModule();",
+            "      }",
+            "      if (executor == null) {",
+            "        throw new IllegalStateException(Executor.class.getCanonicalName()",
+            "            + \" must be set\");",
+            "      }",
+            "      return new DaggerTestClass_SimpleComponent(this);",
+            "    }",
+            "",
+            "    public Builder aModule(AModule aModule) {",
+            "      if (aModule == null) {",
+            "        throw new NullPointerException();",
+            "      }",
+            "      this.aModule = aModule;",
+            "      return this;",
+            "    }",
+            "",
+            "    public Builder bModule(BModule bModule) {",
+            "      if (bModule == null) {",
+            "        throw new NullPointerException();",
+            "      }",
+            "      this.bModule = bModule;",
+            "      return this;",
+            "    }",
+            "",
+            "    public Builder testClass$SimpleComponent_MonitoringModule(",
+            "        TestClass$SimpleComponent_MonitoringModule",
+            "        testClass$SimpleComponent_MonitoringModule) {",
+            "      if (testClass$SimpleComponent_MonitoringModule == null) {",
+            "        throw new NullPointerException();",
+            "      }",
+            "      this.testClass$SimpleComponent_MonitoringModule =",
+            "          testClass$SimpleComponent_MonitoringModule;",
+            "      return this;",
+            "    }",
+            "",
+            "    public Builder executor(Executor executor) {",
+            "      if (executor == null) {",
+            "        throw new NullPointerException();",
+            "      }",
+            "      this.executor = executor;",
+            "      return this;",
+            "    }",
+            "  }",
+            "}");
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(generatedComponent);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ProductionGraphValidationTest.java b/compiler/src/test/java/dagger/internal/codegen/ProductionGraphValidationTest.java
new file mode 100644
index 0000000..6fc8716
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ProductionGraphValidationTest.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.google.testing.compile.JavaFileObjects;
+import java.util.Arrays;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+/**
+ * Unit tests for {@link BindingGraphValidator} that exercise producer-specific logic.
+ */
+@RunWith(JUnit4.class)
+public class ProductionGraphValidationTest {
+  @Test public void componentWithUnprovidedInput() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.MyComponent",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "@ProductionComponent(modules = FooModule.class)",
+        "interface MyComponent {",
+        "  ListenableFuture<Foo> getFoo();",
+        "}");
+    JavaFileObject module = JavaFileObjects.forSourceLines("test.FooModule",
+        "package test;",
+        "",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "",
+        "class Foo {}",
+        "class Bar {}",
+        "",
+        "@ProducerModule",
+        "class FooModule {",
+        "  @Produces Foo foo(Bar bar) {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(Arrays.asList(module, component))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("test.Bar cannot be provided without an @Inject constructor or from "
+            + "an @Provides- or @Produces-annotated method.")
+            .in(component).onLine(8);
+  }
+
+  @Test public void componentProductionWithNoDependencyChain() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "final class TestClass {",
+        "  interface A {}",
+        "",
+        "  @ProductionComponent()",
+        "  interface AComponent {",
+        "    ListenableFuture<A> getA();",
+        "  }",
+        "}");
+    String expectedError =
+        "test.TestClass.A cannot be provided without an @Provides- or @Produces-annotated method.";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(11);
+  }
+
+  @Test public void provisionDependsOnProduction() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "final class TestClass {",
+        "  interface A {}",
+        "  interface B {}",
+        "",
+        "  @Module",
+        "  final class AModule {",
+        "    @Provides A a(B b) {",
+        "      return null;",
+        "    }",
+        "  }",
+        "",
+        "  @ProducerModule",
+        "  final class BModule {",
+        "    @Produces ListenableFuture<B> b() {",
+        "      return null;",
+        "    }",
+        "  }",
+        "",
+        "  @ProductionComponent(modules = {AModule.class, BModule.class})",
+        "  interface AComponent {",
+        "    ListenableFuture<A> getA();",
+        "  }",
+        "}");
+    String expectedError =
+        "test.TestClass.A is a provision, which cannot depend on a production.";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(30);
+  }
+
+  @Test public void provisionEntryPointDependsOnProduction() {
+    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
+        "package test;",
+        "",
+        "import com.google.common.util.concurrent.ListenableFuture;",
+        "import dagger.producers.ProducerModule;",
+        "import dagger.producers.Produces;",
+        "import dagger.producers.ProductionComponent;",
+        "",
+        "final class TestClass {",
+        "  interface A {}",
+        "",
+        "  @ProducerModule",
+        "  final class AModule {",
+        "    @Produces ListenableFuture<A> a() {",
+        "      return null;",
+        "    }",
+        "  }",
+        "",
+        "  @ProductionComponent(modules = AModule.class)",
+        "  interface AComponent {",
+        "    A getA();",
+        "  }",
+        "}");
+    String expectedError =
+        "test.TestClass.A is a provision entry-point, which cannot depend on a production.";
+    assertAbout(javaSource()).that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError).in(component).onLine(20);
+  }
+
+  @Test
+  public void monitoringDependsOnUnboundType() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.TestClass",
+            "package test;",
+            "",
+            "import com.google.common.util.concurrent.ListenableFuture;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import dagger.producers.ProducerModule;",
+            "import dagger.producers.Produces;",
+            "import dagger.producers.ProductionComponent;",
+            "import dagger.producers.monitoring.ProductionComponentMonitor;",
+            "",
+            "import static dagger.Provides.Type.SET;",
+            "",
+            "final class TestClass {",
+            "  interface A {}",
+            "",
+            "  @Module",
+            "  final class MonitoringModule {",
+            "    @Provides(type = SET)",
+            "    ProductionComponentMonitor.Factory monitorFactory(A unbound) {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @ProducerModule",
+            "  final class StringModule {",
+            "    @Produces ListenableFuture<String> str() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @ProductionComponent(modules = {MonitoringModule.class, StringModule.class})",
+            "  interface StringComponent {",
+            "    ListenableFuture<String> getString();",
+            "  }",
+            "}");
+    String expectedError =
+        "test.TestClass.A cannot be provided without an @Provides-annotated method.";
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError)
+        .in(component)
+        .onLine(33);
+  }
+
+  @Test
+  public void monitoringDependsOnProduction() {
+    JavaFileObject component =
+        JavaFileObjects.forSourceLines(
+            "test.TestClass",
+            "package test;",
+            "",
+            "import com.google.common.util.concurrent.ListenableFuture;",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "import dagger.producers.ProducerModule;",
+            "import dagger.producers.Produces;",
+            "import dagger.producers.ProductionComponent;",
+            "import dagger.producers.monitoring.ProductionComponentMonitor;",
+            "",
+            "import static dagger.Provides.Type.SET;",
+            "",
+            "final class TestClass {",
+            "  interface A {}",
+            "",
+            "  @Module",
+            "  final class MonitoringModule {",
+            "    @Provides(type = SET) ProductionComponentMonitor.Factory monitorFactory(A a) {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @ProducerModule",
+            "  final class StringModule {",
+            "    @Produces A a() {",
+            "      return null;",
+            "    }",
+            "",
+            "    @Produces ListenableFuture<String> str() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @ProductionComponent(modules = {MonitoringModule.class, StringModule.class})",
+            "  interface StringComponent {",
+            "    ListenableFuture<String> getString();",
+            "  }",
+            "}");
+    String expectedError =
+        "java.util.Set<dagger.producers.monitoring.ProductionComponentMonitor.Factory> is a"
+            + " provision, which cannot depend on a production.";
+    assertAbout(javaSource())
+        .that(component)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(expectedError)
+        .in(component)
+        .onLine(36);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/RepeatedModuleValidationTest.java b/compiler/src/test/java/dagger/internal/codegen/RepeatedModuleValidationTest.java
new file mode 100644
index 0000000..6bf0c9e
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/RepeatedModuleValidationTest.java
@@ -0,0 +1,121 @@
+package dagger.internal.codegen;
+
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public class RepeatedModuleValidationTest {
+  private static final JavaFileObject MODULE_FILE =
+      JavaFileObjects.forSourceLines(
+          "test.TestModule",
+          "package test;",
+          "",
+          "import dagger.Module;",
+          "",
+          "@Module",
+          "final class TestModule {}");
+
+  @Test
+  public void moduleRepeatedInSubcomponentFactoryMethod() {
+    JavaFileObject subcomponentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestSubcomponent",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "",
+            "@Subcomponent(modules = TestModule.class)",
+            "interface TestSubcomponent {",
+            "}");
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component(modules = TestModule.class)",
+            "interface TestComponent {",
+            "  TestSubcomponent newTestSubcomponent(TestModule module);",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(MODULE_FILE, subcomponentFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("This module is present in test.TestComponent.")
+        .in(componentFile)
+        .onLine(7)
+        .atColumn(51);
+  }
+
+  @Test
+  public void moduleRepeatedInSubcomponentBuilderMethod() {
+    JavaFileObject subcomponentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestSubcomponent",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "",
+            "@Subcomponent(modules = TestModule.class)",
+            "interface TestSubcomponent {",
+            "  @Subcomponent.Builder",
+            "  interface Builder {",
+            "    Builder testModule(TestModule testModule);",
+            "    TestSubcomponent build();",
+            "  }",
+            "}");
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component(modules = TestModule.class)",
+            "interface TestComponent {",
+            "  TestSubcomponent.Builder newTestSubcomponentBuilder();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(MODULE_FILE, subcomponentFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+    // TODO(gak): assert about the warning when we have that ability
+  }
+
+  @Test
+  public void moduleRepeatedButNotPassed() {
+    JavaFileObject subcomponentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestSubcomponent",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "",
+            "@Subcomponent(modules = TestModule.class)",
+            "interface TestSubcomponent {",
+            "}");
+    JavaFileObject componentFile =
+        JavaFileObjects.forSourceLines(
+            "test.TestComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component(modules = TestModule.class)",
+            "interface TestComponent {",
+            "  TestSubcomponent newTestSubcomponent();",
+            "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(MODULE_FILE, subcomponentFile, componentFile))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError();
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/SubcomponentBuilderValidationTest.java b/compiler/src/test/java/dagger/internal/codegen/SubcomponentBuilderValidationTest.java
new file mode 100644
index 0000000..6311a90
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/SubcomponentBuilderValidationTest.java
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+/** Tests for {@link dagger.Subcomponent.Builder} validation. */
+@RunWith(JUnit4.class)
+public class SubcomponentBuilderValidationTest {
+  
+  private static final ErrorMessages.SubcomponentBuilderMessages MSGS =
+      new ErrorMessages.SubcomponentBuilderMessages();
+  
+  @Test
+  public void testRefSubcomponentAndSubBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent child();",
+        "  ChildComponent.Builder builder();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static interface Builder {",
+        "    ChildComponent build();",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.moreThanOneRefToSubcomponent(),
+            "test.ChildComponent", "[child(), builder()]"))
+        .in(componentFile);
+  }
+  
+  @Test
+  public void testRefSubBuilderTwiceFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder builder1();",
+        "  ChildComponent.Builder builder2();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static interface Builder {",
+        "    ChildComponent build();",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.moreThanOneRefToSubcomponent(),
+            "test.ChildComponent", "[builder1(), builder2()]"))
+        .in(componentFile);
+  }
+  
+  @Test
+  public void testMoreThanOneBuilderFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder1 build();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static interface Builder1 {",
+        "    ChildComponent build();",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  static interface Builder2 {",
+        "    ChildComponent build();",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.moreThanOne(),
+            "[test.ChildComponent.Builder1, test.ChildComponent.Builder2]"))
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderGenericsFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder1 build();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder<T> {",
+        "     ChildComponent build();",
+        "  }",           
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.generics())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderNotInComponentFails() {
+    JavaFileObject builder = JavaFileObjects.forSourceLines("test.Builder",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent.Builder",
+        "interface Builder {}");
+    assertAbout(javaSource()).that(builder)
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeInComponent())
+        .in(builder);
+  }
+  
+  @Test
+  public void testBuilderMissingBuildMethodFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder1 build();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.missingBuildMethod())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testPrivateBuilderFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  private interface Builder {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.isPrivate())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testNonStaticBuilderFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  abstract class Builder {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeStatic())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testNonAbstractBuilderFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static class Builder {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeAbstract())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderOneCxtorWithArgsFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static abstract class Builder {",
+        "    Builder(String unused) {}",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderMoreThanOneCxtorFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  static abstract class Builder {",
+        "    Builder() {}",
+        "    Builder(String unused) {}",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderEnumFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  enum Builder {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.mustBeClassOrInterface())
+        .in(childComponentFile);
+  }
+  
+  @Test
+  public void testBuilderBuildReturnsWrongTypeFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    String build();",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.buildMustReturnComponentType())
+            .in(childComponentFile).onLine(9);
+  }
+  
+  @Test
+  public void testInheritedBuilderBuildReturnsWrongTypeFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent {",
+        "    String build();",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedBuildMustReturnComponentType(), "build"))
+            .in(childComponentFile).onLine(12);
+  }
+  
+  @Test
+  public void testTwoBuildMethodsFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    ChildComponent create();",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(String.format(MSGS.twoBuildMethods(), "build()"))
+            .in(childComponentFile).onLine(10);
+  }
+  
+  @Test
+  public void testInheritedTwoBuildMethodsFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent {",
+        "    ChildComponent build();",
+        "    ChildComponent create();",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedTwoBuildMethods(), "create()", "build()"))
+            .in(childComponentFile).onLine(13);
+  }
+  
+  @Test
+  public void testMoreThanOneArgFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    Builder set(String s, Integer i);",
+        "    Builder set(Number n, Double d);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMustTakeOneArg())
+            .in(childComponentFile).onLine(10)
+        .and().withErrorContaining(MSGS.methodsMustTakeOneArg())
+            .in(childComponentFile).onLine(11);
+  }
+  
+  @Test
+  public void testInheritedMoreThanOneArgFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent {",
+        "    ChildComponent build();",
+        "    Builder set1(String s, Integer i);",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMustTakeOneArg(),
+                "set1(java.lang.String,java.lang.Integer)"))
+            .in(childComponentFile).onLine(13);
+  }
+  
+  @Test
+  public void testSetterReturningNonVoidOrBuilderFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    String set(Integer i);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMustReturnVoidOrBuilder())
+            .in(childComponentFile).onLine(10);
+  }
+  
+  @Test
+  public void testInheritedSetterReturningNonVoidOrBuilderFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent {",
+        "    ChildComponent build();",
+        "    String set(Integer i);",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMustReturnVoidOrBuilder(),
+                "set(java.lang.Integer)"))
+            .in(childComponentFile).onLine(13);    
+  }
+  
+  @Test
+  public void testGenericsOnSetterMethodFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    <T> Builder set(T t);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(MSGS.methodsMayNotHaveTypeParameters())
+            .in(childComponentFile).onLine(10);
+  }
+  
+  @Test
+  public void testGenericsOnInheritedSetterMethodFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent {",
+        "    ChildComponent build();",
+        "    <T> Builder set(T t);",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent {}",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)"))
+            .in(childComponentFile).onLine(13);    
+  }
+  
+  @Test
+  public void testMultipleSettersPerTypeFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    void set1(String s);",
+        "    void set2(String s);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.manyMethodsForType(),
+                  "java.lang.String", "[set1(java.lang.String), set2(java.lang.String)]"))
+            .in(childComponentFile).onLine(8);
+  }
+  
+  @Test
+  public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() {
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "abstract class ChildComponent {",
+        "  interface Parent<T> {",
+        "    void set1(T t);",
+        "  }",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder extends Parent<String> {",
+        "    ChildComponent build();",
+        "    void set2(String s);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.manyMethodsForType(),
+                  "java.lang.String", "[set1(T), set2(java.lang.String)]"))
+            .in(childComponentFile).onLine(12);
+  }
+  
+  @Test
+  public void testExtraSettersFails() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder build();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent build();",
+        "    void set1(String s);",
+        "    void set2(Integer s);",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            String.format(MSGS.extraSetters(),
+                  "[void test.ChildComponent.Builder.set1(String),"
+                  + " void test.ChildComponent.Builder.set2(Integer)]"))
+            .in(childComponentFile).onLine(8);
+    
+  }
+  
+  @Test
+  public void testMissingSettersFail() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  TestModule(String unused) {}",
+        "  @Provides String s() { return null; }",
+        "}");
+    JavaFileObject module2File = JavaFileObjects.forSourceLines("test.Test2Module",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class Test2Module {",
+        "  @Provides Integer i() { return null; }",
+        "}");
+    JavaFileObject module3File = JavaFileObjects.forSourceLines("test.Test3Module",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class Test3Module {",
+        "  Test3Module(String unused) {}",
+        "  @Provides Double d() { return null; }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "import javax.inject.Provider;",
+        "",
+        "@Component",
+        "interface ParentComponent {",
+        "  ChildComponent.Builder build();",        
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = {TestModule.class, Test2Module.class, Test3Module.class})",
+        "interface ChildComponent {",
+        "  String string();",
+        "  Integer integer();",
+        "",
+        "  @Subcomponent.Builder",
+        "  interface Builder {",
+        "    ChildComponent create();",
+        "  }",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(moduleFile,
+            module2File,
+            module3File,
+            componentFile,
+            childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            // Ignores Test2Module because we can construct it ourselves.
+            // TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies.
+            String.format(MSGS.missingSetters(), "[test.TestModule, test.Test3Module]"))
+            .in(childComponentFile).onLine(11);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/SubcomponentValidationTest.java b/compiler/src/test/java/dagger/internal/codegen/SubcomponentValidationTest.java
new file mode 100644
index 0000000..d47c328
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/SubcomponentValidationTest.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableList;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+
+@RunWith(JUnit4.class)
+public final class SubcomponentValidationTest {
+  @Test public void factoryMethod_missingModulesWithParameters() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  ChildComponent newChildComponent();",
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = ModuleWithParameters.class)",
+        "interface ChildComponent {",
+        "  Object object();",
+        "}");
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ModuleWithParameters",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class ModuleWithParameters {",
+        "  private final Object object;",
+        "",
+        "  ModuleWithParameters(Object object) {",
+        "    this.object = object;",
+        "  }",
+        "",
+        "  @Provides Object object() {",
+        "    return object;",
+        "  }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile, moduleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "test.ChildComponent requires modules which have no visible default constructors. "
+                + "Add the following modules as parameters to this method: "
+                + "test.ModuleWithParameters")
+        .in(componentFile).onLine(7);
+  }
+
+  @Test public void factoryMethod_nonModuleParameter() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  ChildComponent newChildComponent(String someRandomString);",
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "Subcomponent factory methods may only accept modules, but java.lang.String is not.")
+        .in(componentFile).onLine(7).atColumn(43);
+  }
+
+  @Test public void factoryMethod_duplicateParameter() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "final class TestModule {}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  ChildComponent newChildComponent(TestModule testModule1, TestModule testModule2);",
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = TestModule.class)",
+        "interface ChildComponent {}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "A module may only occur once an an argument in a Subcomponent factory method, "
+                + "but test.TestModule was already passed.")
+        .in(componentFile).onLine(7).atColumn(71);
+  }
+
+  @Test public void factoryMethod_superflouousModule() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "",
+        "@Module",
+        "final class TestModule {}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  ChildComponent newChildComponent(TestModule testModule);",
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "interface ChildComponent {}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, componentFile, childComponentFile))
+    .processedWith(new ComponentProcessor())
+    .failsToCompile()
+    .withErrorContaining(
+        "test.TestModule is present as an argument to the test.ChildComponent factory method, but "
+            + "is not one of the modules used to implement the subcomponent.")
+                .in(componentFile).onLine(7);
+  }
+
+  @Test public void missingBinding() {
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "",
+        "@Module",
+        "final class TestModule {",
+        "  @Provides String provideString(int i) {",
+        "    return Integer.toString(i);",
+        "  }",
+        "}");
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "",
+        "@Component",
+        "interface TestComponent {",
+        "  ChildComponent newChildComponent();",
+        "}");
+    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = TestModule.class)",
+        "interface ChildComponent {",
+        "  String getString();",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, componentFile, childComponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "java.lang.Integer cannot be provided without an @Inject constructor or from an "
+                + "@Provides-annotated method");
+  }
+
+  @Test public void subcomponentOnConcreteType() {
+    JavaFileObject subcomponentFile = JavaFileObjects.forSourceLines("test.NotASubcomponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent",
+        "final class NotASubcomponent {}");
+    assertAbout(javaSources()).that(ImmutableList.of(subcomponentFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("interface");
+  }
+
+  @Test public void scopeMismatch() {
+    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
+        "package test;",
+        "",
+        "import dagger.Component;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Component",
+        "@Singleton",
+        "interface ParentComponent {",
+        "  ChildComponent childComponent();",
+        "}");
+    JavaFileObject subcomponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
+        "package test;",
+        "",
+        "import dagger.Subcomponent;",
+        "",
+        "@Subcomponent(modules = ChildModule.class)",
+        "interface ChildComponent {",
+        "  Object getObject();",
+        "}");
+    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ChildModule",
+        "package test;",
+        "",
+        "import dagger.Module;",
+        "import dagger.Provides;",
+        "import javax.inject.Singleton;",
+        "",
+        "@Module",
+        "final class ChildModule {",
+        "  @Provides @Singleton Object provideObject() { return null; }",
+        "}");
+    assertAbout(javaSources()).that(ImmutableList.of(componentFile, subcomponentFile, moduleFile))
+        .processedWith(new ComponentProcessor())
+        .failsToCompile()
+        .withErrorContaining("@Singleton");
+  }
+
+  @Test
+  public void delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent() {
+    JavaFileObject parentComponentFile =
+        JavaFileObjects.forSourceLines(
+            "test.ParentComponent",
+            "package test;",
+            "",
+            "import dagger.Component;",
+            "",
+            "@Component",
+            "interface ParentComponent {",
+            "  ChildComponent childComponent();",
+            "  Dep1 getDep1();",
+            "  Dep2 getDep2();",
+            "}");
+    JavaFileObject childComponentFile =
+        JavaFileObjects.forSourceLines(
+            "test.ChildComponent",
+            "package test;",
+            "",
+            "import dagger.Subcomponent;",
+            "",
+            "@Subcomponent(modules = ChildModule.class)",
+            "interface ChildComponent {",
+            "  Object getObject();",
+            "}");
+    JavaFileObject childModuleFile =
+        JavaFileObjects.forSourceLines(
+            "test.ChildModule",
+            "package test;",
+            "",
+            "import dagger.Module;",
+            "import dagger.Provides;",
+            "",
+            "@Module",
+            "final class ChildModule {",
+            "  @Provides Object provideObject(A a) { return null; }",
+            "}");
+    JavaFileObject aFile =
+        JavaFileObjects.forSourceLines(
+            "test.A",
+            "package test;",
+            "",
+            "import javax.inject.Inject;",
+            "",
+            "final class A {",
+            "  @Inject public A(NeedsDep1 a, Dep1 b, Dep2 c) { }",
+            "  @Inject public void methodA() { }",
+            "}");
+    JavaFileObject needsDep1File =
+        JavaFileObjects.forSourceLines(
+            "test.NeedsDep1",
+            "package test;",
+            "",
+            "import javax.inject.Inject;",
+            "",
+            "final class NeedsDep1 {",
+            "  @Inject public NeedsDep1(Dep1 d) { }",
+            "}");
+    JavaFileObject dep1File =
+        JavaFileObjects.forSourceLines(
+            "test.Dep1",
+            "package test;",
+            "",
+            "import javax.inject.Inject;",
+            "",
+            "final class Dep1 {",
+            "  @Inject public Dep1() { }",
+            "  @Inject public void dep1Method() { }",
+            "}");
+    JavaFileObject dep2File =
+        JavaFileObjects.forSourceLines(
+            "test.Dep2",
+            "package test;",
+            "",
+            "import javax.inject.Inject;",
+            "",
+            "final class Dep2 {",
+            "  @Inject public Dep2() { }",
+            "  @Inject public void dep2Method() { }",
+            "}");
+
+    JavaFileObject componentGeneratedFile =
+        JavaFileObjects.forSourceLines(
+            "DaggerParentComponent",
+            "package test;",
+            "",
+            "import dagger.MembersInjector;",
+            "import javax.annotation.Generated;",
+            "import javax.inject.Provider;",
+            "",
+            "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+            "public final class DaggerParentComponent implements ParentComponent {",
+            "  private MembersInjector<Dep1> dep1MembersInjector;",
+            "  private Provider<Dep1> dep1Provider;",
+            "  private MembersInjector<Dep2> dep2MembersInjector;",
+            "  private Provider<Dep2> dep2Provider;",
+            "",
+            "  private DaggerParentComponent(Builder builder) {  ",
+            "    assert builder != null;",
+            "    initialize(builder);",
+            "  }",
+            "",
+            "  public static Builder builder() {  ",
+            "    return new Builder();",
+            "  }",
+            "",
+            "  public static ParentComponent create() {  ",
+            "    return builder().build();",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\")",
+            "  private void initialize(final Builder builder) {  ",
+            "    this.dep1MembersInjector = Dep1_MembersInjector.create();",
+            "    this.dep1Provider = Dep1_Factory.create(dep1MembersInjector);",
+            "    this.dep2MembersInjector = Dep2_MembersInjector.create();",
+            "    this.dep2Provider = Dep2_Factory.create(dep2MembersInjector);",
+            "  }",
+            "",
+            "  @Override",
+            "  public Dep1 getDep1() {  ",
+            "    return dep1Provider.get();",
+            "  }",
+            "",
+            "  @Override",
+            "  public Dep2 getDep2() {  ",
+            "    return dep2Provider.get();",
+            "  }",
+            "",
+            "  @Override",
+            "  public ChildComponent childComponent() {  ",
+            "    return new ChildComponentImpl();",
+            "  }",
+            "",
+            "  public static final class Builder {",
+            "    private Builder() {  ",
+            "    }",
+            "  ",
+            "    public ParentComponent build() {  ",
+            "      return new DaggerParentComponent(this);",
+            "    }",
+            "  }",
+            "",
+            "  private final class ChildComponentImpl implements ChildComponent {",
+            "    private final ChildModule childModule;",
+            "    private MembersInjector<A> aMembersInjector;",
+            "    private Provider<NeedsDep1> needsDep1Provider;",
+            "    private Provider<A> aProvider;",
+            "    private Provider<Object> provideObjectProvider;",
+            "  ",
+            "    private ChildComponentImpl() {  ",
+            "      this.childModule = new ChildModule();",
+            "      initialize();",
+            "    }",
+            "",
+            "    @SuppressWarnings(\"unchecked\")",
+            "    private void initialize() {  ",
+            "      this.aMembersInjector = A_MembersInjector.create();",
+            "      this.needsDep1Provider = NeedsDep1_Factory.create(",
+            "          DaggerParentComponent.this.dep1Provider);",
+            "      this.aProvider = A_Factory.create(",
+            "          aMembersInjector,",
+            "          needsDep1Provider,",
+            "          DaggerParentComponent.this.dep1Provider,",
+            "          DaggerParentComponent.this.dep2Provider);",
+            "      this.provideObjectProvider = ChildModule_ProvideObjectFactory.create(",
+            "          childModule, aProvider);",
+            "    }",
+            "  ",
+            "    @Override",
+            "    public Object getObject() {  ",
+            "      return provideObjectProvider.get();",
+            "    }",
+            "  }",
+            "}");
+    assertAbout(javaSources())
+        .that(
+            ImmutableList.of(
+                parentComponentFile,
+                childComponentFile,
+                childModuleFile,
+                aFile,
+                needsDep1File,
+                dep1File,
+                dep2File))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(componentGeneratedFile);
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/ValidationReportTest.java b/compiler/src/test/java/dagger/internal/codegen/ValidationReportTest.java
new file mode 100644
index 0000000..d7f4451
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/ValidationReportTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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 com.google.common.collect.ImmutableSet;
+import com.google.testing.compile.JavaFileObjects;
+import dagger.internal.codegen.ValidationReport.Builder;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+
+@RunWith(JUnit4.class)
+public class ValidationReportTest {
+  private static final JavaFileObject TEST_CLASS_FILE =
+      JavaFileObjects.forSourceLines("test.TestClass",
+          "package test;",
+          "",
+          "final class TestClass {}");
+
+  @Test
+  public void basicReport() {
+    assertAbout(javaSource())
+        .that(TEST_CLASS_FILE)
+        .processedWith(
+            new SimpleTestProcessor() {
+              @Override
+              void test() {
+                Builder<TypeElement> reportBuilder =
+                    ValidationReport.about(getTypeElement("test.TestClass"));
+                reportBuilder.addError("simple error");
+                reportBuilder.build().printMessagesTo(processingEnv.getMessager());
+              }
+            })
+        .failsToCompile()
+        .withErrorContaining("simple error")
+        .in(TEST_CLASS_FILE)
+        .onLine(3);
+  }
+
+  @Test
+  public void messageOnDifferentElement() {
+    assertAbout(javaSource())
+        .that(TEST_CLASS_FILE)
+        .processedWith(
+            new SimpleTestProcessor() {
+              @Override
+              void test() {
+                Builder<TypeElement> reportBuilder =
+                    ValidationReport.about(getTypeElement("test.TestClass"));
+                reportBuilder.addError("simple error", getTypeElement(String.class));
+                reportBuilder.build().printMessagesTo(processingEnv.getMessager());
+              }
+            })
+        .failsToCompile()
+        .withErrorContaining("[java.lang.String] simple error")
+        .in(TEST_CLASS_FILE)
+        .onLine(3);
+  }
+
+  @Test
+  public void subreport() {
+    assertAbout(javaSource())
+        .that(TEST_CLASS_FILE)
+        .processedWith(
+            new SimpleTestProcessor() {
+              @Override
+              void test() {
+                Builder<TypeElement> reportBuilder =
+                    ValidationReport.about(getTypeElement("test.TestClass"));
+                reportBuilder.addError("simple error");
+                ValidationReport<TypeElement> parentReport =
+                    ValidationReport.about(getTypeElement(String.class))
+                        .addSubreport(reportBuilder.build())
+                        .build();
+                assertThat(parentReport.isClean()).isFalse();
+                parentReport.printMessagesTo(processingEnv.getMessager());
+              }
+            })
+        .failsToCompile()
+        .withErrorContaining("simple error")
+        .in(TEST_CLASS_FILE)
+        .onLine(3);
+  }
+
+  private static abstract class SimpleTestProcessor extends AbstractProcessor {
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+      return ImmutableSet.of("*");
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      test();
+      return false;
+    }
+
+    protected final TypeElement getTypeElement(Class<?> clazz) {
+      return getTypeElement(clazz.getCanonicalName());
+    }
+
+    protected final TypeElement getTypeElement(String canonicalName) {
+      return processingEnv.getElementUtils().getTypeElement(canonicalName);
+    }
+
+    abstract void test();
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/writer/ClassNameTest.java b/compiler/src/test/java/dagger/internal/codegen/writer/ClassNameTest.java
new file mode 100644
index 0000000..eff01b8
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/writer/ClassNameTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.common.collect.ImmutableList;
+import com.google.testing.compile.CompilationRule;
+import dagger.internal.codegen.writer.ClassNameTest.OuterClass.InnerClass;
+import java.util.Map;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public class ClassNameTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  @Test public void bestGuessForString_simpleClass() {
+    assertThat(ClassName.bestGuessFromString(String.class.getName()))
+        .isEqualTo(ClassName.create("java.lang", "String"));
+  }
+
+  static class OuterClass {
+    static class InnerClass {}
+  }
+
+  @Test public void bestGuessForString_nestedClass() {
+    assertThat(ClassName.bestGuessFromString(Map.Entry.class.getCanonicalName()))
+        .isEqualTo(ClassName.create("java.util", ImmutableList.of("Map"), "Entry"));
+    assertThat(ClassName.bestGuessFromString(OuterClass.InnerClass.class.getCanonicalName()))
+        .isEqualTo(
+            ClassName.create("dagger.internal.codegen.writer",
+                ImmutableList.of("ClassNameTest", "OuterClass"), "InnerClass"));
+  }
+
+  @Test public void bestGuessForString_defaultPackage() {
+    assertThat(ClassName.bestGuessFromString("SomeClass"))
+        .isEqualTo(ClassName.create("", "SomeClass"));
+    assertThat(ClassName.bestGuessFromString("SomeClass.Nested"))
+        .isEqualTo(ClassName.create("", ImmutableList.of("SomeClass"), "Nested"));
+    assertThat(ClassName.bestGuessFromString("SomeClass.Nested.EvenMore"))
+        .isEqualTo(ClassName.create("", ImmutableList.of("SomeClass", "Nested"), "EvenMore"));
+  }
+
+  @Test public void bestGuessForString_confusingInput() {
+    try {
+      ClassName.bestGuessFromString("com.test.$");
+      fail();
+    } catch (IllegalArgumentException expected) {}
+    try {
+      ClassName.bestGuessFromString("com.test.LooksLikeAClass.pkg");
+      fail();
+    } catch (IllegalArgumentException expected) {}
+    try {
+      ClassName.bestGuessFromString("!@#$gibberish%^&*");
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  @Test public void classNameFromTypeElement() {
+    Elements elements = compilationRule.getElements();
+    TypeElement element = elements.getTypeElement(Object.class.getCanonicalName());
+    assertThat(ClassName.fromTypeElement(element).canonicalName())
+        .isEqualTo("java.lang.Object");
+  }
+
+  @Test public void peerNamed_topLevelClass() {
+    Elements elements = compilationRule.getElements();
+    TypeElement element = elements.getTypeElement(ClassNameTest.class.getCanonicalName());
+    ClassName className = ClassName.fromTypeElement(element);
+    ClassName peerName = className.peerNamed("Foo");
+    assertThat(peerName.canonicalName())
+        .isEqualTo("dagger.internal.codegen.writer.Foo");
+  }
+
+  @Test public void peerNamed_nestedClass() {
+    Elements elements = compilationRule.getElements();
+    TypeElement element = elements.getTypeElement(OuterClass.class.getCanonicalName());
+    ClassName className = ClassName.fromTypeElement(element);
+    ClassName peerName = className.peerNamed("Foo");
+    assertThat(peerName.canonicalName())
+        .isEqualTo("dagger.internal.codegen.writer.ClassNameTest.Foo");
+  }
+
+  @Test public void peerNamed_deeplyNestedClass() {
+    Elements elements = compilationRule.getElements();
+    TypeElement element = elements.getTypeElement(InnerClass.class.getCanonicalName());
+    ClassName className = ClassName.fromTypeElement(element);
+    ClassName peerName = className.peerNamed("Foo");
+    assertThat(peerName.canonicalName())
+        .isEqualTo("dagger.internal.codegen.writer.ClassNameTest.OuterClass.Foo");
+  }
+
+  @Test public void fromClass_NonNestedClass() {
+    ClassName className = ClassName.fromClass(ClassNameTest.class);
+    assertThat(className.canonicalName()).isEqualTo(
+        "dagger.internal.codegen.writer.ClassNameTest");
+  }
+
+  @Test public void fromClass_NestedClass() {
+    ClassName className = ClassName.fromClass(InnerClass.class);
+    assertThat(className.canonicalName()).isEqualTo(
+        "dagger.internal.codegen.writer.ClassNameTest.OuterClass.InnerClass");
+  }
+
+  @Test public void fromClass_classFileName() {
+    ClassName className = ClassName.fromClass(InnerClass.class);
+    assertThat(className.classFileName('_')).isEqualTo("ClassNameTest_OuterClass_InnerClass");
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/writer/JavaWriterTest.java b/compiler/src/test/java/dagger/internal/codegen/writer/JavaWriterTest.java
new file mode 100644
index 0000000..e775f74
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/writer/JavaWriterTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class JavaWriterTest {
+  @Test public void referencedAndDeclaredSimpleName() {
+    JavaWriter javaWriter = JavaWriter.inPackage("test");
+    ClassWriter topClass = javaWriter.addClass("Top");
+    topClass.addNestedClass("Middle").addNestedClass("Bottom");
+    topClass.addField(ClassName.create("some.other.pkg", "Bottom"), "field");
+    assertThat(topClass.toString()).doesNotContain("import some.other.pkg.Bottom;");
+  }
+}
diff --git a/compiler/src/test/java/dagger/internal/codegen/writer/TypeNamesTest.java b/compiler/src/test/java/dagger/internal/codegen/writer/TypeNamesTest.java
new file mode 100644
index 0000000..ec82e96
--- /dev/null
+++ b/compiler/src/test/java/dagger/internal/codegen/writer/TypeNamesTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.writer;
+
+import com.google.testing.compile.CompilationRule;
+import java.nio.charset.Charset;
+import java.util.Set;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(JUnit4.class)
+public class TypeNamesTest {
+  @Rule public final CompilationRule compilation = new CompilationRule();
+
+  private TypeElement getElement(Class<?> clazz) {
+    return compilation.getElements().getTypeElement(clazz.getCanonicalName());
+  }
+
+  private TypeMirror getType(Class<?> clazz) {
+    return getElement(clazz).asType();
+  }
+
+  @Test
+  public void forTypeMirror_basicTypes() {
+    assertThat(TypeNames.forTypeMirror(getType(Object.class)))
+        .isEqualTo(ClassName.fromClass(Object.class));
+    assertThat(TypeNames.forTypeMirror(getType(Charset.class)))
+        .isEqualTo(ClassName.fromClass(Charset.class));
+    assertThat(TypeNames.forTypeMirror(getType(TypeNamesTest.class)))
+        .isEqualTo(ClassName.fromClass(TypeNamesTest.class));
+  }
+
+  @Test
+  public void forTypeMirror_parameterizedType() {
+    DeclaredType setType =
+        compilation.getTypes().getDeclaredType(getElement(Set.class), getType(Object.class));
+    assertThat(TypeNames.forTypeMirror(setType))
+        .isEqualTo(ParameterizedTypeName.create(Set.class, ClassName.fromClass(Object.class)));
+  }
+
+  @Test
+  public void forTypeMirror_typeVariables() {
+    TypeMirror setType = getType(Set.class);
+    assertThat(TypeNames.forTypeMirror(setType))
+        .isEqualTo(ParameterizedTypeName.create(Set.class, TypeVariableName.named("E")));
+  }
+
+  @Test
+  public void forTypeMirror_primitive() {
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.BOOLEAN)))
+        .isEqualTo(PrimitiveName.BOOLEAN);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.BYTE)))
+        .isEqualTo(PrimitiveName.BYTE);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.SHORT)))
+        .isEqualTo(PrimitiveName.SHORT);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.INT)))
+        .isEqualTo(PrimitiveName.INT);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.LONG)))
+        .isEqualTo(PrimitiveName.LONG);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.CHAR)))
+        .isEqualTo(PrimitiveName.CHAR);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.FLOAT)))
+        .isEqualTo(PrimitiveName.FLOAT);
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getPrimitiveType(TypeKind.DOUBLE)))
+        .isEqualTo(PrimitiveName.DOUBLE);
+  }
+
+  @Test
+  public void forTypeMirror_arrays() {
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getArrayType(getType(Object.class))))
+        .isEqualTo(new ArrayTypeName(ClassName.fromClass(Object.class)));
+  }
+
+  @Test
+  public void forTypeMirror_void() {
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getNoType(TypeKind.VOID)))
+        .isEqualTo(VoidName.VOID);
+  }
+
+  @Test
+  public void forTypeMirror_null() {
+    assertThat(TypeNames.forTypeMirror(compilation.getTypes().getNullType()))
+        .isEqualTo(NullName.NULL);
+  }
+}
diff --git a/compiler/src/test/java/dagger/tests/integration/operation/PrimitiveInjectionTest.java b/compiler/src/test/java/dagger/tests/integration/operation/PrimitiveInjectionTest.java
new file mode 100644
index 0000000..58fa263
--- /dev/null
+++ b/compiler/src/test/java/dagger/tests/integration/operation/PrimitiveInjectionTest.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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.tests.integration.operation;
+
+import com.google.testing.compile.JavaFileObjects;
+import dagger.internal.codegen.ComponentProcessor;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static java.util.Arrays.asList;
+
+@RunWith(JUnit4.class)
+public final class PrimitiveInjectionTest {
+
+  // TODO(cgruber): Use @test.ForTest to qualify primitives once qualifier equivalence is working.
+  /*
+  JavaFileObject annotation = JavaFileObjects.forSourceLines("test.ForTest",
+      "package test;",
+      "import javax.inject.Qualifier;",
+      "@Qualifier",
+      "public @interface ForTest {",
+      "}");
+  */
+
+  // TODO(cgruber): Expand test to support more primitive types when b/15512877 is fixed.
+  JavaFileObject primitiveInjectable = JavaFileObjects.forSourceLines("test.PrimitiveInjectable",
+      "package test;",
+      "import javax.inject.Inject;",
+      "class PrimitiveInjectable {",
+      "  @Inject PrimitiveInjectable(int ignored) {}",
+      "}");
+
+  JavaFileObject primitiveModule = JavaFileObjects.forSourceLines("test.PrimitiveModule",
+      "package test;",
+      "import dagger.Module;",
+      "import dagger.Provides;",
+      "@Module",
+      "class PrimitiveModule {",
+      "  @Provides int primitiveInt() { return Integer.MAX_VALUE; }",
+      "}");
+
+  JavaFileObject component = JavaFileObjects.forSourceLines("test.PrimitiveComponent",
+      "package test;",
+      "import dagger.Component;",
+      "import dagger.Provides;",
+      "@Component(modules = PrimitiveModule.class)",
+      "interface PrimitiveComponent {",
+      "  int primitiveInt();",
+      "  PrimitiveInjectable primitiveInjectable();",
+      "}");
+
+  JavaFileObject expectedComponent = JavaFileObjects.forSourceLines(
+      "test.DaggerPrimitiveComponent",
+      "package test;",
+      "",
+      "import javax.annotation.Generated;",
+      "import javax.inject.Provider;",
+      "",
+      "@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
+      "public final class DaggerPrimitiveComponent implements PrimitiveComponent {",
+      "  private Provider<Integer> primitiveIntProvider;",
+      "  private Provider<PrimitiveInjectable> primitiveInjectableProvider;",
+      "",
+      "  private DaggerPrimitiveComponent(Builder builder) {",
+      "    assert builder != null;",
+      "    initialize(builder);",
+      "  }",
+      "",
+      "  public static Builder builder() {",
+      "    return new Builder();",
+      "  }",
+      "",
+      "  public static PrimitiveComponent create() {",
+      "    return builder().build();",
+      "  }",
+      "",
+      "  @SuppressWarnings(\"unchecked\")",
+      "  private void initialize(final Builder builder) {",
+      "    this.primitiveIntProvider =",
+      "        PrimitiveModule_PrimitiveIntFactory.create(builder.primitiveModule);",
+      "    this.primitiveInjectableProvider =",
+      "        PrimitiveInjectable_Factory.create(primitiveIntProvider);",
+      "  }",
+      "",
+      "  @Override",
+      "  public int primitiveInt() {",
+      "    return primitiveIntProvider.get();",
+      "  }",
+      "",
+      "  @Override",
+      "  public PrimitiveInjectable primitiveInjectable() {",
+      "    return primitiveInjectableProvider.get();",
+      "  }",
+      "",
+      "  public static final class Builder {",
+      "    private PrimitiveModule primitiveModule;",
+      "",
+      "    private Builder() {",
+      "    }",
+      "",
+      "    public PrimitiveComponent build() {",
+      "      if (primitiveModule == null) {",
+      "        this.primitiveModule = new PrimitiveModule();",
+      "      }",
+      "      return new DaggerPrimitiveComponent(this);",
+      "    }",
+      "",
+      "    public Builder primitiveModule(PrimitiveModule primitiveModule) {",
+      "      if (primitiveModule == null) {",
+      "        throw new NullPointerException();",
+      "      }",
+      "      this.primitiveModule = primitiveModule;",
+      "      return this;",
+      "    }",
+      "  }",
+      "}");
+
+  @Test public void primitiveArrayTypesAllInjected() {
+    assert_().about(javaSources())
+        .that(asList(component, primitiveInjectable, primitiveModule))
+        .processedWith(new ComponentProcessor())
+        .compilesWithoutError()
+        .and().generatesSources(expectedComponent);
+  }
+}
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..eab9dd8
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2012 Square, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>dagger</artifactId>
+  <name>Dagger</name>
+
+  <properties>
+    <!-- Runtime must remain Java6 to support android. -->
+    <java.version>1.6</java.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>animal-sniffer-maven-plugin</artifactId>
+        <version>1.8</version><!-- 1.9+ requires JDK7 on the build machine -->
+        <executions>
+          <execution>
+            <id>sniff-api</id>
+            <goals><goal>check</goal></goals>
+          </execution>
+        </executions>
+        <configuration>
+          <signature>
+            <groupId>org.codehaus.mojo.signature</groupId>
+            <artifactId>java16</artifactId>
+            <version>1.0</version>
+          </signature>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <excludePackageNames>dagger.internal:dagger.internal.*</excludePackageNames>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/core/src/main/java/dagger/Component.java b/core/src/main/java/dagger/Component.java
new file mode 100644
index 0000000..7d72401
--- /dev/null
+++ b/core/src/main/java/dagger/Component.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Qualifier;
+import javax.inject.Scope;
+import javax.inject.Singleton;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Annotates an interface or abstract class for which a fully-formed, dependency-injected
+ * implementation is to be generated from a set of {@linkplain #modules}. The generated class will
+ * have the name of the type annotated with {@code @Component} prepended with {@code Dagger}. For
+ * example, {@code @Component interface MyComponent {...}} will produce an implementation named
+ * {@code DaggerMyComponent}.
+ *
+ * <a name="component-methods">
+ * <h2>Component methods</h2>
+ * </a>
+ *
+ * <p>Every type annotated with {@code @Component} must contain at least one abstract component
+ * method. Component methods may have any name, but must have signatures that conform to either
+ * {@linkplain Provider provision} or {@linkplain MembersInjector members-injection} contracts.
+ *
+ * <a name="provision-methods">
+ * <h3>Provision methods</h3>
+ * </a>
+ *
+ * <p>Provision methods have no parameters and return an {@link Inject injected} or
+ * {@link Provides provided} type. Each method may have a {@link Qualifier} annotation as well. The
+ * following are all valid provision method declarations: <pre><code>
+ *   SomeType getSomeType();
+ *   {@literal Set<SomeType>} getSomeTypes();
+ *   {@literal @PortNumber} int getPortNumber();
+ * </code></pre>
+ *
+ * <p>Provision methods, like typical {@link Inject injection} sites, may use {@link Provider} or
+ * {@link Lazy} to more explicitly control provision requests. A {@link Provider} allows the user
+ * of the component to request provision any number of times by calling {@link Provider#get}. A
+ * {@link Lazy} will only ever request a single provision, but will defer it until the first call to
+ * {@link Lazy#get}. The following provision methods all request provision of the same type, but
+ * each implies different semantics: <pre><code>
+ *   SomeType getSomeType();
+ *   {@literal Provider<SomeType>} getSomeTypeProvider();
+ *   {@literal Lazy<SomeType>} getLazySomeType();
+ * </code></pre>
+ *
+ * <a name="members-injection-methods">
+ * <h3>Members-injection methods</h3>
+ * </a>
+ *
+ * <p>Members-injection methods have a single parameter and inject dependencies into each of the
+ * {@link Inject}-annotated fields and methods of the passed instance. A members-injection method
+ * may be void or return its single parameter as a convenience for chaining. The following are all
+ * valid members-injection method declarations: <pre><code>
+ *   void injectSomeType(SomeType someType);
+ *   SomeType injectAndReturnSomeType(SomeType someType);
+ * </code></pre>
+ *
+ * <p>A method with no parameters that returns a {@link MembersInjector} is equivalent to a members
+ * injection method. Calling {@link MembersInjector#injectMembers} on the returned object will
+ * perform the same work as a members injection method. For example: <pre><code>
+ *   {@literal MembersInjector<SomeType>} getSomeTypeMembersInjector();
+ * </code></pre>
+ *
+ * <h4>A note about covariance</h4>
+ *
+ * <p>While a members-injection method for a type will accept instances of its subtypes, only
+ * {@link Inject}-annotated members of the parameter type and its supertypes will be injected;
+ * members of subtypes will not. For example, given the following types, only {@code a} and
+ * {@code b} will be injected into an instance of {@code Child} when it is passed to the
+ * members-injection method {@code injectSelf(Self instance)}: <pre><code>
+ *   class Parent {
+ *     {@literal @}Inject A a;
+ *   }
+ *
+ *   class Self extends Parent {
+ *     {@literal @}Inject B b;
+ *   }
+ *
+ *   class Child extends Self {
+ *     {@literal @}Inject C c;
+ *   }
+ * </code></pre>
+ *
+ * <a name="instantiation">
+ * <h2>Instantiation</h2>
+ * </a>
+ *
+ * <p>Component implementations are primarily instantiated via a generated
+ * <a href="http://en.wikipedia.org/wiki/Builder_pattern">builder</a>. An instance of the builder
+ * is obtained using the {@code builder()} method on the component implementation.
+ * If a nested {@code @Component.Builder} type exists in the component, the {@code builder()}
+ * method will return a generated implementation of that type.  If no nested
+ * {@code @Component.Builder} exists, the returned builder has a method to set each of the
+ * {@linkplain #modules} and component {@linkplain #dependencies} named with the
+ * <a href="http://en.wikipedia.org/wiki/CamelCase">lower camel case</a> version of the module
+ * or dependency type. Each component dependency and module without a visible default constructor
+ * must be set explicitly, but any module with a default or no-args constructor accessible to the
+ * component implementation may be elided. This is an example usage of a component builder:
+ * <pre><code>
+ *   public static void main(String[] args) {
+ *     OtherComponent otherComponent = ...;
+ *     MyComponent component = DaggerMyComponent.builder()
+ *         // required because component dependencies must be set
+ *         .otherComponent(otherComponent)
+ *         // required because FlagsModule has constructor parameters
+ *         .flagsModule(new FlagsModule(args))
+ *         // may be elided because a no-args constructor is visible
+ *         .myApplicationModule(new MyApplicationModule())
+ *         .build();
+ *   }
+ * </code></pre>
+ *
+ * <p>In the case that a component has no component dependencies and only no-arg modules, the
+ * generated component will also have a factory method {@code create()}.
+ * {@code SomeComponent.create()} and {@code SomeComponent.builder().build()} are both valid and
+ * equivalent.
+ *
+ * <a name="scope">
+ * <h2>Scope</h2>
+ * </a>
+ *
+ * <p>Each Dagger component can be associated with a scope by annotating it with the
+ * {@linkplain Scope scope annotation}. The component implementation ensures that there is only one
+ * provision of each scoped binding per instance of the component. If the component declares a
+ * scope, it may only contain unscoped bindings or bindings of that scope anywhere in the graph. For
+ * example: <pre><code>
+ *   {@literal @}Singleton {@literal @}Component
+ *   interface MyApplicationComponent {
+ *     // this component can only inject types using unscoped or {@literal @}Singleton bindings
+ *   }
+ * </code></pre>
+ *
+ * <p>In order to get the proper behavior associated with a scope annotation, it is the caller's
+ * responsibility to instantiate new component instances when appropriate. A {@link Singleton}
+ * component, for instance, should only be instantiated once per application, while a
+ * {@code RequestScoped} component should be instantiated once per request. Because components are
+ * self-contained implementations, exiting a scope is as simple as dropping all references to the
+ * component instance.
+ *
+ * <a name="component-relationships">
+ * <h2>Component relationships</h2>
+ * </a>
+ *
+ * <p>While there is much utility in isolated components with purely unscoped bindings, many
+ * applications will call for multiple components with multiple scopes to interact. Dagger provides
+ * two mechanisms for relating components.
+ *
+ * <a name="subcomponents">
+ * <h3>Subcomponents</h3>
+ * </a>
+ *
+ * <p>The simplest way to relate two components is by declaring a {@link Subcomponent}. A
+ * subcomponent behaves exactly like a component, but has its implementation generated within
+ * a parent component or subcomponent. That relationship allows the subcomponent implementation to
+ * inherit the <em>entire</em> binding graph from its parent when it is declared. For that reason,
+ * a subcomponent isn't evaluated for completeness until it is associated with a parent.
+ *
+ * <p>Subcomponents are declared via a factory method on a parent component or subcomponent. The
+ * method may have any name, but must return the subcomponent. The factory method's parameters may
+ * be any number of the subcomponent's modules, but must at least include those without visible
+ * no-arg constructors. The following is an example of a factory method that creates a
+ * request-scoped subcomponent from a singleton-scoped parent: <pre><code>
+ *   {@literal @}Singleton {@literal @}Component
+ *   interface ApplicationComponent {
+ *     // component methods...
+ *
+ *     RequestComponent newRequestComponent(RequestModule requestModule);
+ *   }
+ * </code></pre>
+ *
+ * <a name="component-dependencies">
+ * <h3>Component dependencies</h3>
+ * </a>
+ *
+ * <p>While subcomponents are the simplest way to compose subgraphs of bindings, subcomponents are
+ * tightly coupled with the parents; they may use any binding defined by their ancestor component
+ * and subcomponents. As an alternative, components can use bindings only from another
+ * <em>component interface</em> by declaring a {@linkplain #dependencies component dependency}. When
+ * a type is used as a component dependency, each <a href="#provision-methods">provision method</a>
+ * on the dependency is bound as a provider. Note that <em>only</em> the bindings exposed as
+ * provision methods are available through component dependencies.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
+@Target(TYPE)
+@Documented
+public @interface Component {
+  /**
+   * A list of classes annotated with {@link Module} whose bindings are used to generate the
+   * component implementation. Note that through the use of {@link Module#includes} the full set of
+   * modules used to implement the component may include more modules that just those listed here.
+   */
+  Class<?>[] modules() default {};
+
+  /**
+   * A list of types that are to be used as <a href="#component-dependencies">component
+   * dependencies</a>.
+   */
+  Class<?>[] dependencies() default {};
+
+  /**
+   * A builder for a component. Components may have a single nested static abstract class or
+   * interface annotated with {@code @Component.Builder}.  If they do, then the component's
+   * generated builder will match the API in the type.  Builders must follow some rules:
+   * <ul>
+   * <li> A single abstract method with no arguments must exist, and must return the component.
+   *      (This is typically the {@code build()} method.)
+   * <li> All other abstract methods must take a single argument and must return void,
+   *      the Builder type, or a supertype of the builder.
+   * <li> Each component dependency <b>must</b> have an abstract setter method.
+   * <li> Each module dependency that Dagger can't instantiate itself (e.g, the module
+   *      doesn't have a visible no-args constructor) <b>must</b> have an abstract setter method.
+   *      Other module dependencies (ones that Dagger can instantiate) are allowed, but not required.
+   * <li> Non-abstract methods are allowed, but ignored as far as validation and builder generation
+   *      are concerned.
+   * </ul>
+   * 
+   * For example, this could be a valid Component with a Builder: <pre><code>
+   * {@literal @}Component(modules = {BackendModule.class, FrontendModule.class})
+   * interface MyComponent {
+   *   MyWidget myWidget();
+   *   
+   *   {@literal @}Component.Builder
+   *   interface Builder {
+   *     MyComponent build();
+   *     Builder backendModule(BackendModule bm);
+   *     Builder frontendModule(FrontendModule fm);
+   *   }
+   * }</code></pre>
+   */
+  @Target(TYPE)
+  @Documented
+  @interface Builder {}
+}
diff --git a/core/src/main/java/dagger/Lazy.java b/core/src/main/java/dagger/Lazy.java
new file mode 100644
index 0000000..e04cc03
--- /dev/null
+++ b/core/src/main/java/dagger/Lazy.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2012 Square, Inc.
+ *
+ * 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;
+
+/**
+ * A handle to a lazily-computed value. Each {@code Lazy} computes its value on
+ * the first call to {@code get()} and remembers that same value for all
+ * subsequent calls to {@code get()}.
+ *
+ * <p>{@code null} is not a supported value.  Implementations of {@code Lazy}
+ * are expected to throw {@link NullPointerException} if the computed value is
+ * {@code null}.
+ *
+ * <h2>Example</h2>
+ * The differences between <strong>direct injection</strong>, <strong>provider
+ * injection</strong> and <strong>lazy injection</strong> are best demonstrated
+ * with an example. Start with a module that computes a different integer for
+ * each use:<pre><code>
+ *   {@literal @Module}
+ *   final class CounterModule {
+ *     int next = 100;
+ *
+ *     {@literal @Provides} Integer provideInteger() {
+ *       System.out.println("computing...");
+ *       return next++;
+ *     }
+ *   }
+ * </code></pre>
+ *
+ * <h3>Direct Injection</h3>
+ * This class injects that integer and prints it 3 times:<pre><code>
+ *   final class DirectCounter {
+ *     {@literal @Inject} Integer value;
+ *
+ *     void print() {
+ *       System.out.println("printing...");
+ *       System.out.println(value);
+ *       System.out.println(value);
+ *       System.out.println(value);
+ *     }
+ *   }
+ * </code></pre>
+ * Injecting a {@code DirectCounter} and invoking {@code print()} reveals that
+ * the value is computed <i>before</i> it is required:<pre><code>
+ *   computing...
+ *   printing...
+ *   100
+ *   100
+ *   100
+ * </code></pre>
+ *
+ * <h3>Provider Injection</h3>
+ * This class injects a {@linkplain javax.inject.Provider provider} for the
+ * integer. It calls {@code Provider.get()} 3 times and prints each result:
+ * <pre><code>
+ *   final class ProviderCounter {
+ *     {@literal @Inject Provider<Integer> provider;}
+ *
+ *     void print() {
+ *       System.out.println("printing...");
+ *       System.out.println(provider.get());
+ *       System.out.println(provider.get());
+ *       System.out.println(provider.get());
+ *     }
+ *   }
+ * </code></pre>
+ * Injecting a {@code ProviderCounter} and invoking {@code print()} shows that
+ * a new value is computed each time {@code Provider.get()} is used:<pre><code>
+ *   printing...
+ *   computing...
+ *   100
+ *   computing...
+ *   101
+ *   computing...
+ *   102
+ * </code></pre>
+ *
+ * <h3>Lazy Injection</h3>
+ * This class injects a {@code Lazy} for the integer. Like the provider above,
+ * it calls {@code Lazy.get()} 3 times and prints each result:<pre><code>
+ *   final class LazyCounter {
+ *     {@literal @Inject Lazy<Integer> lazy;}
+ *
+ *     void print() {
+ *       System.out.println("printing...");
+ *       System.out.println(lazy.get());
+ *       System.out.println(lazy.get());
+ *       System.out.println(lazy.get());
+ *     }
+ *   }
+ * </code></pre>
+ * Injecting a {@code LazyCounter} and invoking {@code print()} shows that a new
+ * value is computed immediately before it is needed. The same value is returned
+ * for all subsequent uses:<pre><code>
+ *   printing...
+ *   computing...
+ *   100
+ *   100
+ *   100
+ * </code></pre>
+ *
+ * <h3>Lazy != Singleton</h3>
+ * Note that each injected {@code Lazy} is independent, and remembers its value
+ * in isolation of other {@code Lazy} instances. In this example, two {@code
+ * LazyCounter} objects are created and {@code print()} is called on each:
+ * <pre><code>
+ *   final class LazyCounters {
+ *     {@literal @Inject} LazyCounter counter1;
+ *     {@literal @Inject} LazyCounter counter2;
+ *
+ *     void print() {
+ *       counter1.print();
+ *       counter2.print();
+ *     }
+ *   }
+ * </code></pre>
+ * The output demonstrates that each {@code Lazy} works independently:
+ * <pre><code>
+ *   printing...
+ *   computing...
+ *   100
+ *   100
+ *   100
+ *   printing...
+ *   computing...
+ *   101
+ *   101
+ *   101
+ * </code></pre>
+ * Use {@link javax.inject.Singleton @Singleton} to share one instance among all
+ * clients, and {@code Lazy} for lazy computation in a single client.
+ */
+public interface Lazy<T> {
+  /**
+   * Return the underlying value, computing the value if necessary. All calls to
+   * the same {@code Lazy} instance will return the same result.
+   *
+   * @throws NullPointerException if the computed value is {@code null}.
+   */
+  T get();
+}
diff --git a/core/src/main/java/dagger/MapKey.java b/core/src/main/java/dagger/MapKey.java
new file mode 100644
index 0000000..106c001
--- /dev/null
+++ b/core/src/main/java/dagger/MapKey.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import dagger.internal.Beta;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.Map;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Identifies annotation types that are used to associate keys with values returned by
+ * {@linkplain Provides provider methods} in order to compose a {@linkplain Provides.Type#MAP map}.
+ *
+ * <p>Every provider method annotated with {@code @Provides(type = MAP)} must also have an
+ * annotation that identifies the key for that map entry. That annotation's type must be annotated
+ * with {@code @MapKey}.
+ *
+ * <p>Typically, the key annotation has a single member, whose value is used as the map key.
+ *
+ * <p>For example, to add an entry to a {@code Map<SomeEnum, Integer>} with key
+ * {@code SomeEnum.FOO}, you could use an annotation called {@code @SomeEnumKey}:
+ *
+ * <pre><code>
+ * {@literal @}MapKey
+ * {@literal @}interface SomeEnumKey {
+ *   SomeEnum value();
+ * }
+ *
+ * {@literal @}Module
+ * class SomeModule {
+ *   {@literal @}Provides(type = MAP)
+ *   {@literal @}SomeEnumKey(SomeEnum.FOO)
+ *   Integer provideFooValue() {
+ *     return 2;
+ *   }
+ * }
+ *
+ * class SomeInjectedType {
+ *   {@literal @}Inject
+ *   SomeInjectedType(Map<SomeEnum, Integer> map) {
+ *     assert map.get(SomeEnum.FOO) == 2;
+ *   }
+ * }
+ * </code></pre>
+ *
+ * <p>If {@code unwrapValue} is true, the annotation's single member can be any type except an
+ * array.
+ *
+ * <p>See {@link dagger.mapkeys} for standard unwrapped map key annotations for keys that are boxed
+ * primitives, strings, or classes.
+ *
+ * <h2>Annotations as keys</h2>
+ *
+ * <p>If {@link #unwrapValue} is false, then the annotation itself is used as the map key. For
+ * example, to add an entry to a {@code Map<MyMapKey, Integer>} map:
+ *
+ * <pre><code>
+ * {@literal @}MapKey(unwrapValue = false)
+ * {@literal @}interface MyMapKey {
+ *   String someString();
+ *   MyEnum someEnum();
+ * }
+ *
+ * {@literal @}Module
+ * class SomeModule {
+ *   {@literal @}Provides(type = MAP)
+ *   {@literal @}MyMapKey(someString = "foo", someEnum = BAR)
+ *   Integer provideFooBarValue() {
+ *     return 2;
+ *   }
+ * }
+ *
+ * class SomeInjectedType {
+ *   {@literal @}Inject
+ *   SomeInjectedType(Map<MyMapKey, Integer> map) {
+ *     assert map.get(new MyMapKeyImpl("foo", MyEnum.BAR)) == 2;
+ *   }
+ * }
+ * </code></pre>
+ *
+ * <p>(Note that there must be a class {@code MyMapKeyImpl} that implements {@code MyMapKey} in
+ * order to call {@link Map#get(Object)} on the provided map.)
+ *
+ */
+@Documented
+@Target(ANNOTATION_TYPE)
+@Retention(RUNTIME)
+@Beta
+public @interface MapKey {
+  /**
+   * True to use the value of the single member of the annotated annotation as the map key; false
+   * to use the annotation instance as the map key.
+   *
+   * <p>If true, the single member must not be an array.
+   */
+  boolean unwrapValue() default true;
+}
diff --git a/core/src/main/java/dagger/MembersInjector.java b/core/src/main/java/dagger/MembersInjector.java
new file mode 100644
index 0000000..d0de7f3
--- /dev/null
+++ b/core/src/main/java/dagger/MembersInjector.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Square, Inc.
+ * Copyright (C) 2009 Google Inc.
+ *
+ * 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;
+
+/**
+ * Injects dependencies into the fields and methods on instances of type {@code T}. Ignores the
+ * presence or absence of an injectable constructor.
+ *
+ * @param <T> type to inject members of
+ *
+ * @author Bob Lee
+ * @author Jesse Wilson
+ * @since 2.0 (since 1.0 without the provision that {@link #injectMembers} cannot accept
+ *      {@code null})
+ */
+public interface MembersInjector<T> {
+
+  /**
+   * Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
+   * absence of an injectable constructor.
+   *
+   * <p>Whenever the object graph creates an instance, it performs this injection automatically
+   * (after first performing constructor injection), so if you're able to let the object graph
+   * create all your objects for you, you'll never need to use this method.
+   *
+   * @param instance into which members are to be injected
+   * @throws NullPointerException if {@code instance} is {@code null}
+   */
+  void injectMembers(T instance);
+}
diff --git a/core/src/main/java/dagger/Module.java b/core/src/main/java/dagger/Module.java
new file mode 100644
index 0000000..05f0f3a
--- /dev/null
+++ b/core/src/main/java/dagger/Module.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Square, Inc.
+ *
+ * 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates a class that contributes to the object graph.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Module {
+  /**
+   * Additional {@code @Module}-annotated classes from which this module is
+   * composed. The de-duplicated contributions of the modules in
+   * {@code includes}, and of their inclusions recursively, are all contributed
+   * to the object graph.
+   */
+  Class<?>[] includes() default {};
+}
diff --git a/core/src/main/java/dagger/Provides.java b/core/src/main/java/dagger/Provides.java
new file mode 100644
index 0000000..741a54a
--- /dev/null
+++ b/core/src/main/java/dagger/Provides.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007 Google Inc.
+ * Copyright (C) 2012 Square, Inc.
+ *
+ * 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;
+
+import dagger.internal.Beta;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Annotates methods of a module to create a provider method binding. The
+ * method's return type is bound to its returned value. The object graph will
+ * pass dependencies to the method as parameters.
+ *
+ * @author Bob Lee
+ */
+@Documented @Target(METHOD) @Retention(RUNTIME)
+public @interface Provides {
+  /** The type of binding into which the return type of the annotated method contributes. */
+  enum Type {
+    /**
+     * The method is the only one which can produce the value for the specified return type. This
+     * is the default behavior.
+     */
+    UNIQUE,
+
+    /**
+     * The method's return type forms the generic type argument of a {@code Set<T>}, and the
+     * returned value is contributed to the set. The object graph will pass dependencies to the
+     * method as parameters. The {@code Set<T>} produced from the accumulation of values will be
+     * immutable.
+     *
+     */
+    SET,
+
+    /**
+     * Like {@link #SET}, except the method's return type is {@code Set<T>}, where any values are
+     * contributed to the set. An example use is to provide a default empty set binding, which is
+     * otherwise not possible using {@link #SET}.
+     *
+     */
+    SET_VALUES,
+
+    /**
+     * The method's return type forms the type argument for the value of a
+     * {@code Map<K, Provider<V>>}, and the combination of the annotated key and the returned value
+     * is contributed to the map as a key/value pair. The {@code Map<K, Provider<V>>} produced from
+     * the accumulation of values will be immutable.
+     *
+     */
+    @Beta
+    MAP;
+  }
+
+  Type type() default Type.UNIQUE;
+}
diff --git a/core/src/main/java/dagger/Subcomponent.java b/core/src/main/java/dagger/Subcomponent.java
new file mode 100644
index 0000000..988f17b
--- /dev/null
+++ b/core/src/main/java/dagger/Subcomponent.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * A subcomponent that inherits the bindings from a parent {@link Component} or
+ * {@link Subcomponent}. The details of how to associate a subcomponent with a parent are described
+ * in the documentation for {@link Component}.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
+@Target(TYPE)
+@Documented
+public @interface Subcomponent {
+  /**
+   * A list of classes annotated with {@link Module} whose bindings are used to generate the
+   * subcomponent implementation.  Note that through the use of {@link Module#includes} the full set
+   * of modules used to implement the subcomponent may include more modules that just those listed
+   * here.
+   */
+  Class<?>[] modules() default {};
+  
+  /**
+   * A builder for a subcomponent.  This follows all the rules of {@link Component.Builder}, except
+   * it must appear in classes annotated with {@link Subcomponent} instead of {@code Component}.
+   * Components can have methods that return a {@link Subcomponent.Builder}-annotated type,
+   * allowing the user to set modules on the subcomponent using their defined API.
+   */
+  @Target(TYPE)
+  @Documented
+  @interface Builder {}
+}
diff --git a/core/src/main/java/dagger/internal/Beta.java b/core/src/main/java/dagger/internal/Beta.java
new file mode 100644
index 0000000..a0a82c6
--- /dev/null
+++ b/core/src/main/java/dagger/internal/Beta.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Signifies that a public API (public class, method or field) is subject to
+ * incompatible changes, or even removal, in a future release. An API bearing
+ * this annotation is exempt from any compatibility guarantees made by its
+ * containing library. Note that the presence of this annotation implies nothing
+ * about the quality or performance of the API in question, only the fact that
+ * it is not "API-frozen."
+ */
+@Documented
+@Retention(SOURCE)
+public @interface Beta {}
diff --git a/core/src/main/java/dagger/internal/Collections.java b/core/src/main/java/dagger/internal/Collections.java
new file mode 100644
index 0000000..55f26eb
--- /dev/null
+++ b/core/src/main/java/dagger/internal/Collections.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+
+final class Collections {
+  /**
+   * The maximum value for a signed 32-bit integer that is equal to a power of 2.
+   */
+  private static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
+
+  private Collections() {
+  }
+
+  /**
+   * Creates a {@link LinkedHashSet} instance, with a high enough "initial capacity" that it
+   * <em>should</em> hold {@code expectedSize} elements without growth.
+   */
+  static <E> LinkedHashSet<E> newLinkedHashSetWithExpectedSize(int expectedSize) {
+    return new LinkedHashSet<E>(calculateInitialCapacity(expectedSize));
+  }
+
+  /**
+   * Creates a {@link LinkedHashMap} instance, with a high enough "initial capacity" that it
+   * <em>should</em> hold {@code expectedSize} elements without growth.
+   */
+  static <K, V> LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) {
+    return new LinkedHashMap<K, V>(calculateInitialCapacity(expectedSize));
+  }
+
+  private static int calculateInitialCapacity(int expectedSize) {
+    if (expectedSize < 3) {
+      return expectedSize + 1;
+    }
+    if (expectedSize < MAX_POWER_OF_TWO) {
+      // This is the calculation used in JDK8 to resize when a putAll
+      // happens; it seems to be the most conservative calculation we
+      // can make.  0.75 is the default load factor.
+      return (int) (expectedSize / 0.75F + 1.0F);
+    }
+    return Integer.MAX_VALUE; // any large value
+  }
+}
diff --git a/core/src/main/java/dagger/internal/DelegateFactory.java b/core/src/main/java/dagger/internal/DelegateFactory.java
new file mode 100644
index 0000000..d1e864d
--- /dev/null
+++ b/core/src/main/java/dagger/internal/DelegateFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import javax.inject.Provider;
+
+/**
+ * A DelegateFactory that is used to stitch Provider/Lazy indirection based dependency cycles.
+ * 
+ * @since 2.0.1
+ */
+public final class DelegateFactory<T> implements Factory<T> {
+  private Provider<T> delegate;
+
+  @Override
+  public T get() {
+    if (delegate == null) {
+      throw new IllegalStateException();
+    }
+    return delegate.get();
+  }
+
+  public void setDelegatedProvider(Provider<T> delegate) {
+    if (delegate == null) {
+      throw new IllegalArgumentException();
+    }
+    if (this.delegate != null) {
+      throw new IllegalStateException();
+    }
+    this.delegate = delegate;
+  }
+}
+
diff --git a/core/src/main/java/dagger/internal/DoubleCheckLazy.java b/core/src/main/java/dagger/internal/DoubleCheckLazy.java
new file mode 100644
index 0000000..d0f1028
--- /dev/null
+++ b/core/src/main/java/dagger/internal/DoubleCheckLazy.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import dagger.Lazy;
+import javax.inject.Provider;
+
+/**
+ * A basic {@link Lazy} implementation that memoizes the value returned from a {@link Provider}
+ * using the double-check idiom described in Effective Java 2: Item 71.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+// TODO(gak): Unify the duplicated code between this and ScopedProvider.
+public final class DoubleCheckLazy<T> implements Lazy<T> {
+  private static final Object UNINITIALIZED = new Object();
+
+  private final Provider<T> provider;
+  private volatile Object instance = UNINITIALIZED;
+
+  private DoubleCheckLazy(Provider<T> provider) {
+    assert provider != null;
+    this.provider = provider;
+  }
+
+  @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
+  @Override
+  public T get() {
+    // to suppress it.
+    Object result = instance;
+    if (result == UNINITIALIZED) {
+      synchronized (this) {
+        result = instance;
+        if (result == UNINITIALIZED) {
+          instance = result = provider.get();
+        }
+      }
+    }
+    return (T) result;
+  }
+
+  public static <T> Lazy<T> create(Provider<T> provider) {
+    if (provider == null) {
+      throw new NullPointerException();
+    }
+    if (provider instanceof Lazy) {
+      @SuppressWarnings("unchecked")
+      final Lazy<T> lazy = (Lazy<T>) provider;
+      // Avoids memoizing a value that is already memoized.
+      // NOTE: There is a pathological case where Provider<P> may implement Lazy<L>, but P and L
+      // are different types using covariant return on get(). Right now this is used with
+      // ScopedProvider<T> exclusively, which is implemented such that P and L are always the same
+      // so it will be fine for that case.
+      return lazy;
+    }
+    return new DoubleCheckLazy<T>(provider);
+  }
+}
diff --git a/core/src/main/java/dagger/internal/Factory.java b/core/src/main/java/dagger/internal/Factory.java
new file mode 100644
index 0000000..3e2774c
--- /dev/null
+++ b/core/src/main/java/dagger/internal/Factory.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Scope;
+
+/**
+ * An {@linkplain Scope unscoped} {@link Provider}. While a {@link Provider} <i>may<i> apply
+ * scoping semantics while providing an instance, a factory implementation is guaranteed to exercise
+ * the binding logic ({@link Inject} constructors, {@link Provides} methods) upon each call to
+ * {@link #get}.
+ *
+ * <p>Note that while subsequent calls to {@link #get} will create new instances for bindings such
+ * as those created by {@link Inject} constructors, a new instance is not guaranteed by all
+ * bindings. For example, {@link Provides} methods may be implemented in ways that return the same
+ * instance for each call.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public interface Factory<T> extends Provider<T> {
+}
diff --git a/core/src/main/java/dagger/internal/InstanceFactory.java b/core/src/main/java/dagger/internal/InstanceFactory.java
new file mode 100644
index 0000000..59b1fcb
--- /dev/null
+++ b/core/src/main/java/dagger/internal/InstanceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+/**
+ * A {@link Factory} implementation that returns a single instance for all invocations of
+ * {@link #get}.
+ *
+ * <p>Note that while this is a {@link Factory} implementation, and thus unscoped, each call to
+ * {@link #get} will always return the same instance.  As such, any scoping applied to this factory
+ * is redundant and unnecessary.  However, using this with the {@link ScopedProvider} is valid and
+ * may be desired for testing or contractual guarantees.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public final class InstanceFactory<T> implements Factory<T> {
+  public static <T> Factory<T> create(T instance) {
+    if (instance == null) {
+      throw new NullPointerException();
+    }
+    return new InstanceFactory<T>(instance);
+  }
+
+  private final T instance;
+
+  private InstanceFactory(T instance) {
+    this.instance = instance;
+  }
+
+  @Override
+  public T get() {
+    return instance;
+  }
+}
diff --git a/core/src/main/java/dagger/internal/MapFactory.java b/core/src/main/java/dagger/internal/MapFactory.java
new file mode 100644
index 0000000..4dac126
--- /dev/null
+++ b/core/src/main/java/dagger/internal/MapFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.inject.Provider;
+
+import static dagger.internal.Collections.newLinkedHashMapWithExpectedSize;
+import static java.util.Collections.unmodifiableMap;
+
+/**
+ * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a
+ * {@code Map<K, V>} when calling {@link #get} (as specified by {@link Factory}).
+ *
+ * @author Chenying Hou
+ * @since 2.0
+ *
+ */
+public final class MapFactory<K, V> implements Factory<Map<K, V>> {
+  private final Map<K, Provider<V>> contributingMap;
+
+  private MapFactory(Map<K, Provider<V>> map) {
+    this.contributingMap = unmodifiableMap(map);
+  }
+
+  /**
+   * Returns a new MapFactory.
+   */
+  public static <K, V> MapFactory<K, V> create(Provider<Map<K, Provider<V>>> mapProviderFactory) {
+    Map<K, Provider<V>> map = mapProviderFactory.get();
+    return new MapFactory<K, V>(map);
+  }
+
+  /**
+   * Returns a {@code Map<K, V>} whose iteration order is that of the elements
+   * given by each of the providers, which are invoked in the order given at creation.
+   */
+  @Override
+  public Map<K, V> get() {
+    Map<K, V> result = newLinkedHashMapWithExpectedSize(contributingMap.size());
+    for (Entry<K, Provider<V>> entry: contributingMap.entrySet()) {
+      result.put(entry.getKey(), entry.getValue().get());
+    }
+    return unmodifiableMap(result);
+  }
+}
diff --git a/core/src/main/java/dagger/internal/MapProviderFactory.java b/core/src/main/java/dagger/internal/MapProviderFactory.java
new file mode 100644
index 0000000..00c0fd3
--- /dev/null
+++ b/core/src/main/java/dagger/internal/MapProviderFactory.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.inject.Provider;
+
+import static dagger.internal.Collections.newLinkedHashMapWithExpectedSize;
+import static java.util.Collections.unmodifiableMap;
+
+/**
+ * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a
+ * {@code Map<K, Provider<V>>} when calling {@link #get} (as specified by {@link Factory}).
+ *
+ * @author Chenying Hou
+ * @since 2.0
+ *
+ */
+public final class MapProviderFactory<K, V> implements Factory<Map<K, Provider<V>>> {
+  private final Map<K, Provider<V>> contributingMap;
+
+  /**
+   * Returns a new {@link Builder}
+   */
+  public static <K, V> Builder<K, V> builder(int size) {
+    return new Builder<K, V>(size);
+  }
+
+  private MapProviderFactory(LinkedHashMap<K, Provider<V>> contributingMap) {
+    this.contributingMap = unmodifiableMap(contributingMap);
+  }
+
+  /**
+   * Returns a {@code Map<K, Provider<V>>} whose iteration order is that of the elements
+   * given by each of the providers, which are invoked in the order given at creation.
+   *
+   */
+  @Override
+  public Map<K, Provider<V>> get() {
+    return this.contributingMap;
+  }
+
+  /**
+   * A builder to help build the {@link MapProviderFactory}
+   */
+  public static final class Builder<K, V> {
+    private final LinkedHashMap<K, Provider<V>> mapBuilder;
+
+    private Builder(int size) {
+      // TODO(user): consider which way to initialize mapBuilder is better
+      this.mapBuilder = newLinkedHashMapWithExpectedSize(size);
+    }
+
+    /**
+     * Returns a new {@link MapProviderFactory}
+     */
+    public MapProviderFactory<K, V> build() {
+      return new MapProviderFactory<K, V>(this.mapBuilder);
+    }
+
+    /**
+     * Associate k with providerOfValue in {@code Builder}
+     */
+    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
+      if (key == null) {
+        throw new NullPointerException("The key is null");
+      }
+      if (providerOfValue == null) {
+        throw new NullPointerException("The provider of the value is null");
+      }
+
+      this.mapBuilder.put(key, providerOfValue);
+      return this;
+    }
+  }
+}
diff --git a/core/src/main/java/dagger/internal/MembersInjectors.java b/core/src/main/java/dagger/internal/MembersInjectors.java
new file mode 100644
index 0000000..ee4c7b4
--- /dev/null
+++ b/core/src/main/java/dagger/internal/MembersInjectors.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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;
+
+import dagger.MembersInjector;
+import javax.inject.Inject;
+
+/**
+ * Basic {@link MembersInjector} implementations used by the framework.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public final class MembersInjectors {
+  /**
+   * Returns a {@link MembersInjector} implementation that injects no members
+   *
+   * <p>Note that there is no verification that the type being injected does not have {@link Inject}
+   * members, so care should be taken to ensure appropriate use.
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> MembersInjector<T> noOp() {
+    return (MembersInjector<T>) NoOpMembersInjector.INSTANCE;
+  }
+
+  private static enum NoOpMembersInjector implements MembersInjector<Object> {
+    INSTANCE;
+
+    @Override public void injectMembers(Object instance) {
+      if (instance == null) {
+        throw new NullPointerException();
+      }
+    }
+  }
+
+  /**
+   * Returns a {@link MembersInjector} that delegates to the {@link MembersInjector} of its
+   * supertype.  This is useful for cases where a type is known not to have its own {@link Inject}
+   * members, but must still inject members on its supertype(s).
+   *
+   * <p>Note that there is no verification that the type being injected does not have {@link Inject}
+   * members, so care should be taken to ensure appropriate use.
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> MembersInjector<T> delegatingTo(MembersInjector<? super T> delegate) {
+    return (MembersInjector<T>) delegate;
+  }
+
+  private MembersInjectors() {}
+}
diff --git a/core/src/main/java/dagger/internal/ScopedProvider.java b/core/src/main/java/dagger/internal/ScopedProvider.java
new file mode 100644
index 0000000..b25db38
--- /dev/null
+++ b/core/src/main/java/dagger/internal/ScopedProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import dagger.Lazy;
+import javax.inject.Provider;
+
+/**
+ * A {@link Provider} implementation that memoizes the result of a {@link Factory} instance.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public final class ScopedProvider<T> implements Provider<T>, Lazy<T> {
+  private static final Object UNINITIALIZED = new Object();
+
+  private final Factory<T> factory;
+  private volatile Object instance = UNINITIALIZED;
+
+  private ScopedProvider(Factory<T> factory) {
+    assert factory != null;
+    this.factory = factory;
+  }
+
+  @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
+  @Override
+  public T get() {
+    // double-check idiom from EJ2: Item 71
+    Object result = instance;
+    if (result == UNINITIALIZED) {
+      synchronized (this) {
+        result = instance;
+        if (result == UNINITIALIZED) {
+          instance = result = factory.get();
+        }
+      }
+    }
+    return (T) result;
+  }
+
+  /** Returns a new scoped provider for the given factory. */
+  public static <T> Provider<T> create(Factory<T> factory) {
+    if (factory == null) {
+      throw new NullPointerException();
+    }
+    return new ScopedProvider<T>(factory);
+  }
+}
diff --git a/core/src/main/java/dagger/internal/SetFactory.java b/core/src/main/java/dagger/internal/SetFactory.java
new file mode 100644
index 0000000..9b73e79
--- /dev/null
+++ b/core/src/main/java/dagger/internal/SetFactory.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.inject.Provider;
+
+import static dagger.internal.Collections.newLinkedHashSetWithExpectedSize;
+import static java.util.Collections.unmodifiableSet;
+
+/**
+ * A {@link Factory} implementation used to implement {@link Set} bindings. This factory always
+ * returns a new {@link Set} instance for each call to {@link #get} (as required by {@link Factory})
+ * whose elements are populated by subsequent calls to their {@link Provider#get} methods.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public final class SetFactory<T> implements Factory<Set<T>> {
+  /**
+   * A message for NPEs that trigger on bad argument lists.
+   */
+  private static final String ARGUMENTS_MUST_BE_NON_NULL =
+      "SetFactory.create() requires its arguments to be non-null";
+
+  /**
+   * Returns the supplied factory.  If there's just one factory, there's no need to wrap it or its
+   * result.
+   */
+  public static <T> Factory<Set<T>> create(Factory<Set<T>> factory) {
+    assert factory != null : ARGUMENTS_MUST_BE_NON_NULL;
+    return factory;
+  }
+  
+  /**
+   * Returns a new factory that creates {@link Set} instances that form the union of the given
+   * {@link Provider} instances.  Callers must not modify the providers array after invoking this
+   * method; no copy is made.
+   */
+  public static <T> Factory<Set<T>> create(
+      @SuppressWarnings("unchecked") Provider<Set<T>>... providers) {
+    assert providers != null : ARGUMENTS_MUST_BE_NON_NULL;
+
+    List<Provider<Set<T>>> contributingProviders = Arrays.asList(providers);
+
+    assert !contributingProviders.contains(null)
+        : "Codegen error?  Null within provider list.";
+    assert !hasDuplicates(contributingProviders)
+        : "Codegen error?  Duplicates in the provider list";
+
+    return new SetFactory<T>(contributingProviders);
+  }
+
+  /**
+   * Returns true if at least one pair of items in (@code original) are equals.
+   */
+  private static boolean hasDuplicates(List<? extends Object> original) {
+    Set<Object> asSet = new HashSet<Object>(original);
+    return original.size() != asSet.size();
+  }
+
+  private final List<Provider<Set<T>>> contributingProviders;
+
+  private SetFactory(List<Provider<Set<T>>> contributingProviders) {
+    this.contributingProviders = contributingProviders;
+  }
+
+  /**
+   * Returns a {@link Set} whose iteration order is that of the elements given by each of the
+   * providers, which are invoked in the order given at creation.
+   *
+   * @throws NullPointerException if any of the delegate {@link Set} instances or elements therein
+   *     are {@code null}
+   */
+  @Override
+  public Set<T> get() {
+    int size = 0;
+
+    // Profiling revealed that this method was a CPU-consuming hotspot in some applications, so
+    // these loops were changed to use c-style for.  Versus enhanced for-each loops, C-style for is 
+    // faster for ArrayLists, at least through Java 8.
+
+    List<Set<T>> providedSets = new ArrayList<Set<T>>(contributingProviders.size());
+    for (int i = 0, c = contributingProviders.size(); i < c; i++) {
+      Provider<Set<T>> provider = contributingProviders.get(i);
+      Set<T> providedSet = provider.get();
+      if (providedSet == null) {
+        throw new NullPointerException(provider + " returned null");
+      }
+      providedSets.add(providedSet);
+      size += providedSet.size();
+    }
+
+    Set<T> result = newLinkedHashSetWithExpectedSize(size);
+    for (int i = 0, c = providedSets.size(); i < c; i++) {
+      for (T element : providedSets.get(i)) {
+        if (element == null) {
+          throw new NullPointerException("a null element was provided");
+        }
+        result.add(element);
+      }
+    }
+    return unmodifiableSet(result);
+  }
+}
diff --git a/core/src/main/java/dagger/mapkeys/ClassKey.java b/core/src/main/java/dagger/mapkeys/ClassKey.java
new file mode 100644
index 0000000..21497c6
--- /dev/null
+++ b/core/src/main/java/dagger/mapkeys/ClassKey.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.mapkeys;
+
+import dagger.MapKey;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/**
+ * A {@link MapKey} annotation for maps with {@code Class<?>} keys.
+ * 
+ * <p>If your map's keys can be constrained, consider using a custom annotation instead, with a
+ * member whose type is {@code Class<? extends Something>}.
+ */
+@Documented
+@Target(METHOD)
+@MapKey
+public @interface ClassKey {
+  Class<?> value();
+}
\ No newline at end of file
diff --git a/core/src/main/java/dagger/mapkeys/IntKey.java b/core/src/main/java/dagger/mapkeys/IntKey.java
new file mode 100644
index 0000000..011b49f
--- /dev/null
+++ b/core/src/main/java/dagger/mapkeys/IntKey.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.mapkeys;
+
+import dagger.MapKey;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/** A {@link MapKey} annotation for maps with {@code int} keys. */
+@Documented
+@Target(METHOD)
+@MapKey
+public @interface IntKey {
+  int value();
+}
\ No newline at end of file
diff --git a/core/src/main/java/dagger/mapkeys/LongKey.java b/core/src/main/java/dagger/mapkeys/LongKey.java
new file mode 100644
index 0000000..183b74d
--- /dev/null
+++ b/core/src/main/java/dagger/mapkeys/LongKey.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.mapkeys;
+
+import dagger.MapKey;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/** A {@link MapKey} annotation for maps with {@code long} keys. */
+@Documented
+@Target(METHOD)
+@MapKey
+public @interface LongKey {
+  long value();
+}
\ No newline at end of file
diff --git a/core/src/main/java/dagger/mapkeys/StringKey.java b/core/src/main/java/dagger/mapkeys/StringKey.java
new file mode 100644
index 0000000..7455a9b
--- /dev/null
+++ b/core/src/main/java/dagger/mapkeys/StringKey.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.mapkeys;
+
+import dagger.MapKey;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/** A {@link MapKey} annotation for maps with {@link String} keys. */
+@Documented
+@Target(METHOD)
+@MapKey
+public @interface StringKey {
+  String value();
+}
\ No newline at end of file
diff --git a/core/src/main/java/dagger/package-info.java b/core/src/main/java/dagger/package-info.java
new file mode 100644
index 0000000..e5cc67f
--- /dev/null
+++ b/core/src/main/java/dagger/package-info.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.
+ */
+
+/**
+ * This package contains the public API for the <a href="http://google.github.io/dagger/">Dagger
+ * 2</a> dependency injection framework.  By building upon
+ * <a href="https://jcp.org/en/jsr/detail?id=330">JSR 330</a>, Dagger 2 provides an
+ * annotation-driven API for dependency injection whose implementation is entirely generated at
+ * compile time by <a href="http://en.wikipedia.org/wiki/Java_annotation#Processing">annotation
+ * processors</a>.
+ *
+ * <p>The entry point into the API is the {@link Component}, which annotates abstract types for
+ * Dagger 2 to implement.  The dependency graph is configured using using annotations such as
+ * {@link Module}, {@link Provides} and {@link javax.inject.Inject}.
+ *
+ * <p>{@code dagger.internal.codegen.ComponentProcessor} is the processor responsible for generating
+ * the implementation.  Dagger uses the annotation procesor
+ * {@linkplain java.util.ServiceLoader service loader} to automatically configure the processor, so
+ * explict build configuration shouldn't be necessary.
+ */
+package dagger;
diff --git a/core/src/test/java/dagger/internal/DoubleCheckLazyTest.java b/core/src/test/java/dagger/internal/DoubleCheckLazyTest.java
new file mode 100644
index 0000000..579e040
--- /dev/null
+++ b/core/src/test/java/dagger/internal/DoubleCheckLazyTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Uninterruptibles;
+import dagger.Lazy;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.Provider;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public class DoubleCheckLazyTest {
+  @Test public void get() throws Exception {
+    int numThreads = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
+
+    final CountDownLatch latch = new CountDownLatch(numThreads);
+    LatchedProvider provider = new LatchedProvider(latch);
+    final Lazy<Object> lazy = DoubleCheckLazy.create(provider);
+
+    List<Callable<Object>> tasks = Lists.newArrayListWithCapacity(numThreads);
+    for (int i = 0; i < numThreads; i++) {
+      tasks.add(new Callable<Object>() {
+        @Override public Object call() throws Exception {
+          latch.countDown();
+          return lazy.get();
+        }
+      });
+    }
+
+    List<Future<Object>> futures = executor.invokeAll(tasks);
+
+    assert_().that(provider.provisions.get()).isEqualTo(1);
+    Set<Object> results = Sets.newIdentityHashSet();
+    for (Future<Object> future : futures) {
+      results.add(future.get());
+    }
+    assert_().that(results.size()).isEqualTo(1);
+  }
+
+  // TODO(gak): reenable this test once we can ensure that factories are no longer providing null
+  @Ignore @Test public void get_null() {
+    Lazy<Object> lazy = DoubleCheckLazy.create(new Provider<Object> () {
+      @Override public Object get() {
+        return null;
+      }
+    });
+    try {
+      lazy.get();
+      fail();
+    } catch (NullPointerException expected) {}
+  }
+
+  private static class LatchedProvider implements Provider<Object> {
+    final AtomicInteger provisions;
+    final CountDownLatch latch;
+
+    LatchedProvider(CountDownLatch latch) {
+      this.latch = latch;
+      this.provisions = new AtomicInteger();
+    }
+
+    @Override
+    public Object get() {
+      if (latch != null) {
+        Uninterruptibles.awaitUninterruptibly(latch);
+      }
+      provisions.incrementAndGet();
+      return new Object();
+    }
+  }
+}
diff --git a/core/src/test/java/dagger/internal/InstanceFactoryTest.java b/core/src/test/java/dagger/internal/InstanceFactoryTest.java
new file mode 100644
index 0000000..acaf20d
--- /dev/null
+++ b/core/src/test/java/dagger/internal/InstanceFactoryTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+
+@RunWith(JUnit4.class)
+public final class InstanceFactoryTest {
+  @Rule public final ExpectedException thrown = ExpectedException.none();
+
+  @Test public void instanceFactory() {
+    Object instance = new Object();
+    Factory<Object> factory = InstanceFactory.create(instance);
+    assert_().that(factory.get()).isEqualTo(instance);
+    assert_().that(factory.get()).isEqualTo(instance);
+    assert_().that(factory.get()).isEqualTo(instance);
+  }
+
+  @Test public void create_throwsNullPointerException() {
+    thrown.expect(NullPointerException.class);
+    InstanceFactory.create(null);
+  }
+}
diff --git a/core/src/test/java/dagger/internal/MapProviderFactoryTest.java b/core/src/test/java/dagger/internal/MapProviderFactoryTest.java
new file mode 100644
index 0000000..b4496e9
--- /dev/null
+++ b/core/src/test/java/dagger/internal/MapProviderFactoryTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.Provider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+
+@RunWith(JUnit4.class)
+@SuppressWarnings("unchecked")
+public class MapProviderFactoryTest {
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void nullKey() {
+    thrown.expect(NullPointerException.class);
+    MapProviderFactory.<String, Integer>builder(1).put(null, incrementingIntegerProvider(1));
+  }
+
+  @Test
+  public void nullValue() {
+    thrown.expect(NullPointerException.class);
+    MapProviderFactory.<String, Integer>builder(1).put("Hello", null);
+  }
+
+  @Test
+  public void iterationOrder() {
+    Provider<Integer> p1 = incrementingIntegerProvider(10);
+    Provider<Integer> p2 = incrementingIntegerProvider(20);
+    Provider<Integer> p3 = incrementingIntegerProvider(30);
+    Provider<Integer> p4 = incrementingIntegerProvider(40);
+    Provider<Integer> p5 = incrementingIntegerProvider(50);
+
+    Factory<Map<String, Provider<Integer>>> factory = MapProviderFactory
+        .<String, Integer>builder(4)
+        .put("two", p2)
+        .put("one", p1)
+        .put("three", p3)
+        .put("one", p5)
+        .put("four", p4)
+        .build();
+
+    Map<String, Provider<Integer>> expectedMap = new LinkedHashMap<String, Provider<Integer>>();
+    expectedMap.put("two", p2);
+    expectedMap.put("one", p1);
+    expectedMap.put("three", p3);
+    expectedMap.put("one", p5);
+    expectedMap.put("four", p4);
+    assert_()
+        .that(factory.get().entrySet())
+        .containsExactlyElementsIn(expectedMap.entrySet())
+        .inOrder();
+  }
+
+  private static Provider<Integer> incrementingIntegerProvider(int seed) {
+    final AtomicInteger value = new AtomicInteger(seed);
+    return new Provider<Integer>() {
+      @Override
+      public Integer get() {
+        return value.getAndIncrement();
+      }
+    };
+  }
+}
diff --git a/core/src/test/java/dagger/internal/ScopedProviderTest.java b/core/src/test/java/dagger/internal/ScopedProviderTest.java
new file mode 100644
index 0000000..84b02c5
--- /dev/null
+++ b/core/src/test/java/dagger/internal/ScopedProviderTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import javax.inject.Provider;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assert_;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests {@link ScopedProvider}.
+ */
+@RunWith(JUnit4.class)
+public class ScopedProviderTest {
+  @Test public void create_nullPointerException() {
+    try {
+      ScopedProvider.create(null);
+      fail();
+    } catch (NullPointerException expected) { }
+  }
+
+  // TODO(gak): reenable this test once we can ensure that factories are no longer providing null
+  @Ignore @Test public void get_nullPointerException() {
+    Provider<Object> scopedProvider = ScopedProvider.create(new Factory<Object>() {
+      @Override public Object get() {
+        return null;
+      }
+    });
+    try {
+      scopedProvider.get();
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void get() {
+    Provider<Integer> scopedProvider = ScopedProvider.create(new Factory<Integer>() {
+      int i = 0;
+
+      @Override public Integer get() {
+        return i++;
+      }
+    });
+    assert_().that(scopedProvider.get()).isEqualTo(0);
+    assert_().that(scopedProvider.get()).isEqualTo(0);
+    assert_().that(scopedProvider.get()).isEqualTo(0);
+  }
+}
diff --git a/core/src/test/java/dagger/internal/SetFactoryTest.java b/core/src/test/java/dagger/internal/SetFactoryTest.java
new file mode 100644
index 0000000..04b9822
--- /dev/null
+++ b/core/src/test/java/dagger/internal/SetFactoryTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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;
+
+import com.google.common.collect.ContiguousSet;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Range;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.Provider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.collect.DiscreteDomain.integers;
+import static com.google.common.truth.Truth.assert_;
+
+@RunWith(JUnit4.class)
+@SuppressWarnings("unchecked")
+public class SetFactoryTest {
+  @Rule public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void providerReturnsNullSet() {
+    Factory<Set<Integer>> factory = SetFactory.create(new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        return null;
+      }
+    }, incrementingIntegerProvider(0));
+    thrown.expect(NullPointerException.class);
+    factory.get();
+  }
+
+  @Test
+  public void providerReturnsNullSet_single() {
+    Factory<Set<Integer>> factory = SetFactory.create(new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        return null;
+      }
+    });
+    thrown.expect(NullPointerException.class);
+    factory.get();
+  }
+
+  @Test
+  public void providerReturnsSetWithNullElement() {
+    Factory<Set<Integer>> factory = SetFactory.create(new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        LinkedHashSet<Integer> result = new LinkedHashSet<Integer>();
+        result.add(1);
+        result.add(null);
+        result.add(3);
+        return result;
+      }
+    });
+    thrown.expect(NullPointerException.class);
+    factory.get();
+  }
+
+  @Test
+  public void providerReturnsSetWithNullElement_single() {
+    Factory<Set<Integer>> factory = SetFactory.create(new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        LinkedHashSet<Integer> result = new LinkedHashSet<Integer>();
+        result.add(1);
+        result.add(null);
+        result.add(3);
+        return result;
+      }
+    }, incrementingIntegerProvider(0));
+    thrown.expect(NullPointerException.class);
+    factory.get();
+  }
+
+  @Test
+  public void invokesProvidersEverytTime() {
+    Factory<Set<Integer>> factory = SetFactory.create(
+        incrementingIntegerProvider(0),
+        incrementingIntegerProvider(10),
+        incrementingIntegerProvider(20));
+    assert_().that(factory.get()).containsExactly(0, 10, 20);
+    assert_().that(factory.get()).containsExactly(1, 11, 21);
+    assert_().that(factory.get()).containsExactly(2, 12, 22);
+  }
+
+  @Test
+  public void iterationOrder() {
+    Factory<Set<Integer>> factory = SetFactory.create(
+        integerSetProvider(Range.closed(5, 9)),
+        integerSetProvider(Range.closed(3, 6)),
+        integerSetProvider(Range.closed(0, 5)));
+    assert_().that(factory.get()).containsExactly(5, 6, 7, 8, 9, 3, 4, 0, 1, 2).inOrder();
+  }
+
+  private static Provider<Set<Integer>> incrementingIntegerProvider(int seed) {
+    final AtomicInteger value = new AtomicInteger(seed);
+    return new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        return ImmutableSet.of(value.getAndIncrement());
+      }
+    };
+  }
+
+  private static Provider<Set<Integer>> integerSetProvider(Range<Integer> range) {
+    final ContiguousSet<Integer> set = ContiguousSet.create(range, integers());
+    return new Provider<Set<Integer>>() {
+      @Override
+      public Set<Integer> get() {
+        return set;
+      }
+    };
+  }
+}
diff --git a/deploy_website.sh b/deploy_website.sh
new file mode 100755
index 0000000..1fde1bd
--- /dev/null
+++ b/deploy_website.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# Deploys the current Dagger website to the gh-pages branch of the GitHub
+# repository. To test the site locally before deploying run `jekyll --server`
+# in the website/ directory.
+
+set -ex
+
+REPO="git@github.com:square/dagger.git"
+GROUP_ID="com.squareup.dagger"
+ARTIFACT_ID="dagger"
+
+DIR=temp-dagger-clone
+
+# Delete any existing temporary website clone
+rm -rf $DIR
+
+# Clone the current repo into temp folder
+git clone $REPO $DIR
+
+# Move working directory into temp folder
+cd $DIR
+
+# Checkout and track the gh-pages branch
+git checkout -t origin/gh-pages
+
+# Delete everything
+rm -rf *
+
+# Copy website files from real repo
+cp -R ../website/* .
+
+# Download the latest javadoc
+curl -L "http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=$GROUP_ID&a=$ARTIFACT_ID&v=LATEST&c=javadoc" > javadoc.zip
+mkdir javadoc
+unzip javadoc.zip -d javadoc
+rm javadoc.zip
+
+# Stage all files in git and create a commit
+git add .
+git add -u
+git commit -m "Website at $(date)"
+
+# Push the new files up to GitHub
+git push origin gh-pages
+
+# Delete our temp folder
+cd ..
+rm -rf $DIR
diff --git a/examples/android-activity-graphs/README.md b/examples/android-activity-graphs/README.md
new file mode 100644
index 0000000..ac3680b
--- /dev/null
+++ b/examples/android-activity-graphs/README.md
@@ -0,0 +1,24 @@
+Example: Android Activity Graphs
+================================
+
+Building on top of the simple Android example, this example demonstrates how it is possible to
+create child graphs for each activity which extend from the global graph.
+
+Some of the advantages of the activity scope:
+
+ * Provides the ability to inject objects which require the activity to be constructed.
+ * Allows for the use of singletons on a per-activity basis. This is a great way to manage a
+   resource that is shared by a bunch of fragments in an activity.
+ * Keeps the global object graph clear of things that can be used only by activities.
+
+While this example only shows the presence of an activity scope, you should be able to see the
+potential for other useful scopes that can be used. For example, having a dedicated object graph
+for the current user session is a great way to manage data that is tied to the currently logged-in
+user.
+
+_Note: The app does not actually do anything when it is run. It is only to show how you can
+ structure Dagger within an Android app_
+
+_Note: The app is in transition to Dagger 2 and may not reflect recommended patterns.  Before
+ we release Dagger 2.0 it will, but until this note is removed, please do not rely on this
+ example as a strong recommendation._
diff --git a/examples/android-activity-graphs/pom.xml b/examples/android-activity-graphs/pom.xml
new file mode 100644
index 0000000..340c59c
--- /dev/null
+++ b/examples/android-activity-graphs/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2013 Square, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.dagger.example</groupId>
+    <artifactId>dagger-example-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>android-activity-graphs</artifactId>
+  <name>Examples: Android - Activity Graphs</name>
+  <packaging>apk</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.android</groupId>
+      <artifactId>android</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.android</groupId>
+      <artifactId>support-v4</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.simpligility.maven.plugins</groupId>
+        <artifactId>android-maven-plugin</artifactId>
+        <extensions>true</extensions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/examples/android-activity-graphs/src/main/AndroidManifest.xml b/examples/android-activity-graphs/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..234406d
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1"
+    android:versionName="1.0.0"
+    package="com.example.dagger.activitygraphs">
+
+  <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17"/>
+
+  <application
+      android:label="app_name"
+      android:name=".DemoApplication">
+    <activity
+        android:label="app_name"
+        android:name=".ui.HomeActivity">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/AbstractActivityComponent.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/AbstractActivityComponent.java
new file mode 100644
index 0000000..430838e
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/AbstractActivityComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import android.app.Activity;
+import dagger.Component;
+
+/**
+ * A base component upon which fragment's components may depend.  Activity-level components
+ * should extend this component.
+ */
+@PerActivity // Subtypes of AbstractActivityComponent should be decorated with @PerActivity.
+@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
+public interface AbstractActivityComponent {
+  Activity activity(); // Expose the activity to sub-graphs.
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ActivityModule.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ActivityModule.java
new file mode 100644
index 0000000..cf5462e
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ActivityModule.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import android.app.Activity;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * A module to wrap the Activity state and expose it to the graph.
+ */
+@Module
+public class ActivityModule {
+  private final Activity activity;
+
+  public ActivityModule(Activity activity) {
+    this.activity = activity;
+  }
+
+  /**
+   * Expose the activity to dependents in the graph.
+   */
+  @Provides @PerActivity Activity activity() {
+    return activity;
+  }
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ApplicationComponent.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ApplicationComponent.java
new file mode 100644
index 0000000..04c2062
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ApplicationComponent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import android.app.Application;
+import android.location.LocationManager;
+import dagger.Component;
+import javax.inject.Singleton;
+
+/**
+ * A component whose lifetime is the life of the application.
+ */
+@Singleton // Constraints this component to one-per-application or unscoped bindings.
+@Component(modules = DemoApplicationModule.class)
+public interface ApplicationComponent {
+  // Field injections of any dependencies of the DemoApplication
+  void inject(DemoApplication application);
+
+  // Exported for child-components.
+  Application application();
+  LocationManager locationManager();
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplication.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplication.java
new file mode 100644
index 0000000..7205733
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplication.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import android.app.Application;
+import android.location.LocationManager;
+import javax.inject.Singleton;
+import javax.inject.Inject;
+
+public class DemoApplication extends Application {
+  private ApplicationComponent applicationComponent;
+
+  // TODO(cgruber): Figure out a better example of something one might inject into the app.
+  @Inject LocationManager locationManager; // to illustrate injecting something into the app.
+
+  @Override public void onCreate() {
+    super.onCreate();
+    applicationComponent = DaggerApplicationComponent.builder()
+        .demoApplicationModule(new DemoApplicationModule(this))
+        .build();
+  }
+
+  public ApplicationComponent component() {
+    return applicationComponent;
+  }
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplicationModule.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplicationModule.java
new file mode 100644
index 0000000..070d2c7
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/DemoApplicationModule.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import android.app.Application;
+import android.location.LocationManager;
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Singleton;
+
+import static android.content.Context.LOCATION_SERVICE;
+
+/**
+ * A module for Android-specific dependencies which require a {@link Context} or
+ * {@link android.app.Application} to create.
+ */
+@Module
+public class DemoApplicationModule {
+  private final Application application;
+
+  public DemoApplicationModule(Application application) {
+    this.application = application;
+  }
+
+  /**
+   * Expose the application to the graph.
+   */
+  @Provides @Singleton Application application() {
+    return application;
+  }
+
+  @Provides @Singleton LocationManager provideLocationManager() {
+    return (LocationManager) application.getSystemService(LOCATION_SERVICE);
+  }
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/PerActivity.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/PerActivity.java
new file mode 100644
index 0000000..d54b193
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/PerActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs;
+
+import java.lang.annotation.Retention;
+import javax.inject.Scope;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * A scoping annotation to permit objects whose lifetime should
+ * conform to the life of the activity to be memoized in the
+ * correct component.
+ */
+@Scope
+@Retention(RUNTIME)
+public @interface PerActivity {
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/ActivityTitleController.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/ActivityTitleController.java
new file mode 100644
index 0000000..c416c75
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/ActivityTitleController.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs.ui;
+
+import android.app.Activity;
+import com.example.dagger.activitygraphs.PerActivity;
+import javax.inject.Inject;
+
+/**
+ * A simple abstraction which provides the ability to set the title on an activity.
+ * <p>
+ * Fragments should not directly modify any part of an activity outside of the view or dialog that
+ * it creates. This class provides a way for fragments to inject a controller that will allow for
+ * control of the activity title. While not exceedingly useful in practice, this concept could be
+ * expanded to things like facilitating control over the action bar, dialogs, notifications, etc.
+ */
+@PerActivity
+public class ActivityTitleController {
+  private final Activity activity;
+
+  @Inject public ActivityTitleController(Activity activity) {
+    this.activity = activity;
+  }
+
+  public void setTitle(CharSequence title) {
+    activity.setTitle(title);
+  }
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeActivity.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeActivity.java
new file mode 100644
index 0000000..1f3bb70
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeActivity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs.ui;
+
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import com.example.dagger.activitygraphs.ActivityModule;
+import com.example.dagger.activitygraphs.DemoApplication;
+import javax.inject.Inject;
+
+public class HomeActivity extends FragmentActivity {
+  @Inject LocationManager locationManager;
+  private HomeComponent component;
+
+  HomeComponent component() {
+    if (component == null) {
+      component = DaggerHomeComponent.builder()
+          .applicationComponent(((DemoApplication) getApplication()).component())
+          .activityModule(new ActivityModule(this))
+          .build();
+    }
+    return component;
+  }
+
+  @Override protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    component().inject(this);
+
+    if (savedInstanceState == null) {
+      getSupportFragmentManager().beginTransaction()
+          .add(android.R.id.content, new HomeFragment())
+          .commit();
+    }
+
+    // TODO do something with the injected dependencies here!
+  }
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeComponent.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeComponent.java
new file mode 100644
index 0000000..84d2a42
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeComponent.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs.ui;
+
+import com.example.dagger.activitygraphs.AbstractActivityComponent;
+import com.example.dagger.activitygraphs.ActivityModule;
+import com.example.dagger.activitygraphs.ApplicationComponent;
+import com.example.dagger.activitygraphs.PerActivity;
+import dagger.Component;
+
+@PerActivity
+@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
+public interface HomeComponent extends AbstractActivityComponent {
+  void inject(HomeActivity homeActivity);
+  void inject(HomeFragment homeFragment);
+}
diff --git a/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeFragment.java b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeFragment.java
new file mode 100644
index 0000000..1df2724
--- /dev/null
+++ b/examples/android-activity-graphs/src/main/java/com/example/dagger/activitygraphs/ui/HomeFragment.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.activitygraphs.ui;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import javax.inject.Inject;
+
+import static android.view.Gravity.CENTER;
+
+public class HomeFragment extends Fragment {
+  @Inject ActivityTitleController titleController;
+
+  @Override public void onActivityCreated(Bundle savedInstanceState) {
+    super.onActivityCreated(savedInstanceState);
+    ((HomeActivity) getActivity()).component().inject(this);
+  }
+
+  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
+      Bundle savedInstanceState) {
+    TextView tv = new TextView(getActivity());
+    tv.setGravity(CENTER);
+    tv.setText("Hello, World");
+    return tv;
+  }
+
+  @Override public void onResume() {
+    super.onResume();
+
+    // Fragments should not modify things outside of their own view. Use an external controller to
+    // ask the activity to change its title.
+    titleController.setTitle("Home Fragment");
+  }
+}
diff --git a/examples/android-simple/README.md b/examples/android-simple/README.md
new file mode 100644
index 0000000..944d015
--- /dev/null
+++ b/examples/android-simple/README.md
@@ -0,0 +1,17 @@
+Example: Android Simple
+=======================
+
+This example demonstrates how to structure an Android application with Dagger.
+
+A custom `Application` class is used to manage a global object graph of objects. Modules are
+assembled with a `getModules` method on the application that can be overridden to add additional
+modules in development versions of your applications or in tests.
+
+Injection of activities is done automatically in a base activity.
+
+_Note: The app does not actually do anything when it is run. It is only to show how you can
+ structure Dagger within an Android app_
+
+_Note: The app is in transition to Dagger 2 and may not reflect recommended patterns.  Before
+ we release Dagger 2.0 it will, but until this note is removed, please do not rely on this
+ example as a strong recommendation._
diff --git a/examples/android-simple/pom.xml b/examples/android-simple/pom.xml
new file mode 100644
index 0000000..fb934e6
--- /dev/null
+++ b/examples/android-simple/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2013 Square, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.dagger.example</groupId>
+    <artifactId>dagger-example-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>android-simple</artifactId>
+  <name>Examples: Android - Simple</name>
+  <packaging>apk</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.android</groupId>
+      <artifactId>android</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.simpligility.maven.plugins</groupId>
+        <artifactId>android-maven-plugin</artifactId>
+        <extensions>true</extensions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/examples/android-simple/src/main/AndroidManifest.xml b/examples/android-simple/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..53c83bf
--- /dev/null
+++ b/examples/android-simple/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1"
+    android:versionName="1.0.0"
+    package="com.example.dagger.simple">
+
+  <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17"/>
+
+  <application
+      android:label="app_name"
+      android:name=".DemoApplication">
+    <activity
+        android:label="app_name"
+        android:name=".ui.HomeActivity">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/examples/android-simple/src/main/java/com/example/dagger/simple/AndroidModule.java b/examples/android-simple/src/main/java/com/example/dagger/simple/AndroidModule.java
new file mode 100644
index 0000000..18184d1
--- /dev/null
+++ b/examples/android-simple/src/main/java/com/example/dagger/simple/AndroidModule.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.simple;
+
+import android.content.Context;
+import android.location.LocationManager;
+import dagger.Module;
+import dagger.Provides;
+import javax.inject.Singleton;
+
+import static android.content.Context.LOCATION_SERVICE;
+
+/**
+ * A module for Android-specific dependencies which require a {@link Context} or
+ * {@link android.app.Application} to create.
+ */
+@Module
+public class AndroidModule {
+  private final DemoApplication application;
+
+  public AndroidModule(DemoApplication application) {
+    this.application = application;
+  }
+
+  /**
+   * Allow the application context to be injected but require that it be annotated with
+   * {@link ForApplication @Annotation} to explicitly differentiate it from an activity context.
+   */
+  @Provides @Singleton @ForApplication Context provideApplicationContext() {
+    return application;
+  }
+
+  @Provides @Singleton LocationManager provideLocationManager() {
+    return (LocationManager) application.getSystemService(LOCATION_SERVICE);
+  }
+}
diff --git a/examples/android-simple/src/main/java/com/example/dagger/simple/DemoActivity.java b/examples/android-simple/src/main/java/com/example/dagger/simple/DemoActivity.java
new file mode 100644
index 0000000..aa09f2d
--- /dev/null
+++ b/examples/android-simple/src/main/java/com/example/dagger/simple/DemoActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.simple;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public abstract class DemoActivity extends Activity {
+  @Override protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    // Perform injection so that when this call returns all dependencies will be available for use.
+    ((DemoApplication) getApplication()).component().inject(this);
+  }
+}
diff --git a/examples/android-simple/src/main/java/com/example/dagger/simple/DemoApplication.java b/examples/android-simple/src/main/java/com/example/dagger/simple/DemoApplication.java
new file mode 100644
index 0000000..55402c6
--- /dev/null
+++ b/examples/android-simple/src/main/java/com/example/dagger/simple/DemoApplication.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.simple;
+
+import android.app.Application;
+import android.location.LocationManager;
+import com.example.dagger.simple.ui.HomeActivity;
+import dagger.Component;
+import java.util.Arrays;
+import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+public class DemoApplication extends Application {
+  
+  @Singleton
+  @Component(modules = AndroidModule.class)
+  public interface ApplicationComponent {
+    void inject(DemoApplication application);
+    void inject(HomeActivity homeActivity);
+    void inject(DemoActivity demoActivity);
+  }
+  
+  @Inject LocationManager locationManager; // for some reason.
+  
+  private ApplicationComponent component;
+
+  @Override public void onCreate() {
+    super.onCreate();
+    component = DaggerDemoApplication_ApplicationComponent.builder()
+        .androidModule(new AndroidModule(this))
+        .build();
+    component().inject(this); // As of now, LocationManager should be injected into this.
+  }
+
+  public ApplicationComponent component() {
+    return component;
+  }
+}
diff --git a/examples/android-simple/src/main/java/com/example/dagger/simple/ForApplication.java b/examples/android-simple/src/main/java/com/example/dagger/simple/ForApplication.java
new file mode 100644
index 0000000..84d2247
--- /dev/null
+++ b/examples/android-simple/src/main/java/com/example/dagger/simple/ForApplication.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.simple;
+
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Qualifier @Retention(RUNTIME)
+public @interface ForApplication {
+}
diff --git a/examples/android-simple/src/main/java/com/example/dagger/simple/ui/HomeActivity.java b/examples/android-simple/src/main/java/com/example/dagger/simple/ui/HomeActivity.java
new file mode 100644
index 0000000..7e33b8e
--- /dev/null
+++ b/examples/android-simple/src/main/java/com/example/dagger/simple/ui/HomeActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.example.dagger.simple.ui;
+
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.util.Log;
+import com.example.dagger.simple.DemoActivity;
+import com.example.dagger.simple.DemoApplication;
+import javax.inject.Inject;
+
+public class HomeActivity extends DemoActivity {
+  @Inject LocationManager locationManager;
+
+  @Override protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    ((DemoApplication) getApplication()).component().inject(this);
+
+    // TODO do something with the injected dependencies here!
+    Log.d("HomeActivity", locationManager.toString());
+  }
+}
diff --git a/examples/pom.xml b/examples/pom.xml
index c12050d..eb4685a 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (C) 2013 The Dagger Authors.
+ Copyright (C) 2013 Google, Inc.
+ Copyright (C) 2013 Square, Inc.
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -18,38 +19,34 @@
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.sonatype.oss</groupId>
-    <artifactId>oss-parent</artifactId>
-    <version>9</version>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
   </parent>
 
   <groupId>com.google.dagger.example</groupId>
   <artifactId>dagger-example-parent</artifactId>
   <packaging>pom</packaging>
   <name>Examples</name>
-  <version>2.17</version>
 
   <modules>
     <module>simple</module>
+    <module>android-simple</module>
+    <module>android-activity-graphs</module>
   </modules>
 
   <!-- Example-only dependencies. -->
   <dependencyManagement>
     <dependencies>
       <dependency>
-        <groupId>com.google.dagger</groupId>
-        <artifactId>dagger</artifactId>
-        <version>${project.version}</version>
+        <groupId>com.google.android</groupId>
+        <artifactId>android</artifactId>
+        <version>4.1.1.4</version>
       </dependency>
       <dependency>
-        <groupId>com.google.dagger</groupId>
-        <artifactId>dagger-compiler</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.google.guava</groupId>
-        <artifactId>guava</artifactId>
-        <version>26.0-jre</version>
+        <groupId>com.google.android</groupId>
+        <artifactId>support-v4</artifactId>
+        <version>r7</version>
       </dependency>
     </dependencies>
   </dependencyManagement>
@@ -64,6 +61,17 @@
             <target>1.6</target>
           </configuration>
         </plugin>
+        <plugin>
+          <groupId>com.simpligility.maven.plugins</groupId>
+          <artifactId>android-maven-plugin</artifactId>
+          <version>4.3.0</version>
+          <configuration>
+            <sdk>
+              <platform>23</platform>
+              <path>${env.ANDROID_HOME}</path>
+            </sdk>
+          </configuration>
+        </plugin>
       </plugins>
     </pluginManagement>
   </build>
diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml
index ffc99dc..0be10b8 100644
--- a/examples/simple/pom.xml
+++ b/examples/simple/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (C) 2012 The Dagger Authors.
+ Copyright (C) 2012 Square, Inc.
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
   <parent>
     <groupId>com.google.dagger.example</groupId>
     <artifactId>dagger-example-parent</artifactId>
-    <version>2.17</version>
+    <version>2.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>simple</artifactId>
@@ -28,32 +28,15 @@
 
   <dependencies>
     <dependency>
-      <!-- Force the correct version of Guava to be on the classpath. -->
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>com.google.dagger</groupId>
-      <artifactId>dagger</artifactId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
     </dependency>
   </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.6.1</version>
-        <configuration>
-          <annotationProcessorPaths>
-            <path>
-              <groupId>com.google.dagger</groupId>
-              <artifactId>dagger-compiler</artifactId>
-              <version>${project.version}</version>
-            </path>
-          </annotationProcessorPaths>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
 </project>
diff --git a/examples/simple/src/main/java/coffee/CoffeeApp.java b/examples/simple/src/main/java/coffee/CoffeeApp.java
index 7a2b9a6..b0a93ec 100644
--- a/examples/simple/src/main/java/coffee/CoffeeApp.java
+++ b/examples/simple/src/main/java/coffee/CoffeeApp.java
@@ -6,12 +6,12 @@
 public class CoffeeApp {
   @Singleton
   @Component(modules = { DripCoffeeModule.class })
-  public interface CoffeeShop {
+  public interface Coffee {
     CoffeeMaker maker();
   }
 
   public static void main(String[] args) {
-    CoffeeShop coffeeShop = DaggerCoffeeApp_CoffeeShop.builder().build();
-    coffeeShop.maker().brew();
+    Coffee coffee = DaggerCoffeeApp_Coffee.builder().build();
+    coffee.maker().brew();
   }
 }
diff --git a/examples/simple/src/main/java/coffee/PumpModule.java b/examples/simple/src/main/java/coffee/PumpModule.java
index df00b86..338ad33 100644
--- a/examples/simple/src/main/java/coffee/PumpModule.java
+++ b/examples/simple/src/main/java/coffee/PumpModule.java
@@ -1,10 +1,11 @@
 package coffee;
 
-import dagger.Binds;
 import dagger.Module;
+import dagger.Provides;
 
 @Module
-abstract class PumpModule {
-  @Binds
-  abstract Pump providePump(Thermosiphon pump);
+class PumpModule {
+  @Provides Pump providePump(Thermosiphon pump) {
+    return pump;
+  }
 }
diff --git a/gwt/BUILD b/gwt/BUILD
deleted file mode 100644
index da73013..0000000
--- a/gwt/BUILD
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   GWT-specific files for Dagger
-
-package(default_visibility = ["//:src"])
-
-load("//tools:maven.bzl", "pom_file", "POM_VERSION")
-
-java_library(
-    name = "gwt",
-    resource_strip_prefix = "gwt/",
-    resources = glob(["**/*.gwt.xml"]),
-    tags = ["maven_coordinates=com.google.dagger:dagger-gwt:" + POM_VERSION],
-    exports = [
-        ":manual_deps",
-        "//java/dagger:core",
-    ],
-)
-
-java_library(
-    name = "manual_deps",
-    tags = [
-        "maven_coordinates=com.google.dagger:dagger:%s:jar:sources" % POM_VERSION,
-        "maven_coordinates=javax.inject:javax.inject:1:jar:sources",
-    ],
-    visibility = ["//visibility:private"],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-gwt",
-    artifact_name = "Dagger GWT",
-    targets = [
-        ":gwt",
-        ":manual_deps",
-    ],
-)
diff --git a/gwt/dagger/Dagger.gwt.xml b/gwt/dagger/Dagger.gwt.xml
deleted file mode 100644
index ad106fd..0000000
--- a/gwt/dagger/Dagger.gwt.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-  Copyright (C) 2015 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.
--->
-<module>
-  <inherits name="javax.inject.Inject" />
-
-  <source path=""/>
-</module>
diff --git a/gwt/javax/inject/Inject.gwt.xml b/gwt/javax/inject/Inject.gwt.xml
deleted file mode 100644
index b634926..0000000
--- a/gwt/javax/inject/Inject.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--
- Copyright (C) 2017 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.
--->
-<module>
-  <source path=""/>
-</module>
diff --git a/jarjar-rules.txt b/jarjar-rules.txt
deleted file mode 100644
index 57941b3..0000000
--- a/jarjar-rules.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# shade guava to avoid conflicts with guava embedded in Error Prone.
-rule com.google.common.** com.google.dagger.common.@1
-rule com.google.auto.** com.google.dagger.auto.@1
diff --git a/java/dagger/BUILD b/java/dagger/BUILD
deleted file mode 100644
index 3485431..0000000
--- a/java/dagger/BUILD
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   A JSR-330 compliant dependency injection system for android and java
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "SOURCE_7_TARGET_7",
-)
-load("//tools:maven.bzl", "POM_VERSION", "pom_file")
-
-java_library(
-    name = "core",
-    srcs = glob(["**/*.java"]),
-    javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX,
-    tags = ["maven_coordinates=com.google.dagger:dagger:" + POM_VERSION],
-    exports = ["@google_bazel_common//third_party/java/jsr330_inject"],
-    deps = [
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger",
-    artifact_name = "Dagger",
-    targets = [":core"],
-)
-
-filegroup(
-    name = "javadoc-srcs",
-    srcs = glob(["**/*"]),
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "core-javadoc",
-    srcs = [":javadoc-srcs"],
-    exclude_packages = ["dagger.internal"],
-    root_packages = ["dagger"],
-    deps = ["@google_bazel_common//third_party/java/jsr330_inject"],
-)
diff --git a/java/dagger/Binds.java b/java/dagger/Binds.java
deleted file mode 100644
index 99b65e2..0000000
--- a/java/dagger/Binds.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates <em>abstract</em> methods of a {@link Module} that delegate bindings. For example, to
- * bind {@link java.util.Random} to {@link java.security.SecureRandom} a module could declare the
- * following: {@code @Binds abstract Random bindRandom(SecureRandom secureRandom);}
- *
- * <p>{@code @Binds} methods are a drop-in replacement for {@link Provides} methods that simply
- * return an injected parameter. Prefer {@code @Binds} because the generated implementation is
- * likely to be more efficient.
- *
- * <p>A {@code @Binds} method:
- *
- * <ul>
- *   <li>Must be {@code abstract}.
- *   <li>May be {@linkplain javax.inject.Scope scoped}.
- *   <li>May be {@linkplain javax.inject.Qualifier qualified}.
- *   <li>Must have a single parameter whose type is assignable to the return type. The return type
- *       declares the bound type (just as it would for a {@literal @}{@link dagger.Provides} method)
- *       and the parameter is the type to which it is bound.
- *       <p>For {@linkplain dagger.multibindings multibindings}, assignability is checked in similar
- *       ways:
- *       <dl>
- *         <dt>{@link dagger.multibindings.IntoSet}
- *         <dd>The parameter must be assignable to the only parameter of {@link java.util.Set#add}
- *             when viewed as a member of the return type — the parameter must be assignable to the
- *             return type.
- *         <dt>{@link dagger.multibindings.ElementsIntoSet}
- *         <dd>The parameter must be assignable to the only parameter of {@link
- *             java.util.Set#addAll} when viewed as a member of the return type — if the return type
- *             is {@code Set<E>}, the parameter must be assignable to {@code Collection<? extends
- *             E>}.
- *         <dt>{@link dagger.multibindings.IntoMap}
- *         <dd>The parameter must be assignable to the {@code value} parameter of {@link
- *             java.util.Map#put} when viewed as a member of a {@link java.util.Map} in which {@code
- *             V} is bound to the return type — the parameter must be assignable to the return type
- *       </dl>
- * </ul>
- */
-@Documented
-@Retention(RUNTIME)
-@Target(METHOD)
-public @interface Binds {}
diff --git a/java/dagger/BindsInstance.java b/java/dagger/BindsInstance.java
deleted file mode 100644
index eab8796..0000000
--- a/java/dagger/BindsInstance.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Marks a method on a {@linkplain Component.Builder component builder} or a parameter on a
- * {@linkplain Component.Factory component factory} as binding an instance to some key within the
- * component.
- *
- * <p>For example:
- *
- * <pre>
- *   {@literal @Component.Builder}
- *   interface Builder {
- *     {@literal @BindsInstance} Builder foo(Foo foo);
- *     {@literal @BindsInstance} Builder bar({@literal @Blue} Bar bar);
- *     ...
- *   }
- *
- *   // or
- *
- *   {@literal @Component.Factory}
- *   interface Factory {
- *     MyComponent newMyComponent(
- *         {@literal @BindsInstance} Foo foo,
- *         {@literal @BindsInstance @Blue} Bar bar);
- *   }
- * </pre>
- *
- * <p>will allow clients of the builder or factory to pass their own instances of {@code Foo} and
- * {@code Bar}, and those instances can be injected within the component as {@code Foo} or
- * {@code @Blue Bar}, respectively.
- *
- * <p>{@code @BindsInstance} arguments may not be {@code null} unless the parameter is annotated
- * with {@code @Nullable}.
- *
- * <p>For builders, {@code @BindsInstance} methods must be called before building the component,
- * unless their parameter is marked {@code @Nullable}, in which case the component will act as
- * though it was called with a {@code null} argument. Primitives, of course, may not be marked
- * {@code @Nullable}.
- *
- * <p>Binding an instance is equivalent to passing an instance to a module constructor and providing
- * that instance, but is often more efficient. When possible, binding object instances should be
- * preferred to using module instances.
- */
-@Documented
-@Retention(RUNTIME)
-@Target({METHOD, PARAMETER})
-@Beta
-public @interface BindsInstance {}
diff --git a/java/dagger/BindsOptionalOf.java b/java/dagger/BindsOptionalOf.java
deleted file mode 100644
index 9a356ff..0000000
--- a/java/dagger/BindsOptionalOf.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-
-/**
- * Annotates methods that declare bindings for {@code Optional} containers of values from bindings
- * that may or may not be present in the component.
- *
- * <p>If a module contains a method declaration like this:
- *
- * <pre>
- * {@literal @BindsOptionalOf} abstract Foo optionalFoo();</pre>
- *
- * then any binding in the component can depend on an {@code Optional} of {@code Foo}. If there is
- * no binding for {@code Foo} in the component, the {@code Optional} will be absent. If there is a
- * binding for {@code Foo} in the component, the {@code Optional} will be present, and its value
- * will be the value given by the binding for {@code Foo}.
- *
- * <p>A {@code @BindsOptionalOf} method:
- *
- * <ul>
- *   <li>must be {@code abstract}
- *   <li>may have a {@linkplain Qualifier qualifier} annotation
- *   <li>must not return {@code void}
- *   <li>must not have parameters
- *   <li>must not throw exceptions
- *   <li>must not return an unqualified type with an {@link Inject @Inject}-annotated constructor,
- *       since such a type is always present
- * </ul>
- *
- * <p>Other bindings may inject any of:
- *
- * <ul>
- *   <li>{@code Optional<Foo>} (unless there is a {@code @Nullable} binding for {@code Foo}; see
- *       below)
- *   <li>{@code Optional<Provider<Foo>>}
- *   <li>{@code Optional<Lazy<Foo>>}
- *   <li>{@code Optional<Provider<Lazy<Foo>>>}
- * </ul>
- *
- * <p>If there is a binding for {@code Foo}, and that binding is {@code @Nullable}, then it is a
- * compile-time error to inject {@code Optional<Foo>}, because {@code Optional} cannot contain
- * {@code null}. You can always inject the other forms, because {@link Provider} and {@link Lazy}
- * can always return {@code null} from their {@code get()} methods.
- *
- * <p>Explicit bindings for any of the above will conflict with a {@code @BindsOptionalOf} binding.
- *
- * <p>If the binding for {@code Foo} is a {@code @Produces} binding, then another {@code @Produces}
- * binding can depend on any of:
- *
- * <ul>
- *   <li>{@code Optional<Foo>}
- *       <!-- TODO(dpb): Update this once producers support nullability checks -->
- *   <li>{@code Optional<Producer<Foo>>}
- *   <li>{@code Optional<Produced<Foo>>}
- * </ul>
- *
- * <p>You can inject either {@code com.google.common.base.Optional} or {@code java.util.Optional}.
- */
-@Documented
-@Beta
-@Retention(RUNTIME)
-@Target(METHOD)
-public @interface BindsOptionalOf {}
diff --git a/java/dagger/Component.java b/java/dagger/Component.java
deleted file mode 100644
index 709b0e6..0000000
--- a/java/dagger/Component.java
+++ /dev/null
@@ -1,365 +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;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-import javax.inject.Scope;
-import javax.inject.Singleton;
-
-/**
- * Annotates an interface or abstract class for which a fully-formed, dependency-injected
- * implementation is to be generated from a set of {@linkplain #modules}. The generated class will
- * have the name of the type annotated with {@code @Component} prepended with {@code Dagger}. For
- * example, {@code @Component interface MyComponent {...}} will produce an implementation named
- * {@code DaggerMyComponent}.
- *
- * <a name="component-methods"></a>
- * <h2>Component methods</h2>
- *
- * <p>Every type annotated with {@code @Component} must contain at least one abstract component
- * method. Component methods may have any name, but must have signatures that conform to either
- * {@linkplain Provider provision} or {@linkplain MembersInjector members-injection} contracts.
- *
- * <a name="provision-methods"></a>
- * <h3>Provision methods</h3>
- *
- * <p>Provision methods have no parameters and return an {@link Inject injected} or {@link Provides
- * provided} type. Each method may have a {@link Qualifier} annotation as well. The following are
- * all valid provision method declarations:
- *
- * <pre><code>
- *   SomeType getSomeType();
- *   {@literal Set<SomeType>} getSomeTypes();
- *   {@literal @PortNumber} int getPortNumber();
- * </code></pre>
- *
- * <p>Provision methods, like typical {@link Inject injection} sites, may use {@link Provider} or
- * {@link Lazy} to more explicitly control provision requests. A {@link Provider} allows the user of
- * the component to request provision any number of times by calling {@link Provider#get}. A {@link
- * Lazy} will only ever request a single provision, but will defer it until the first call to {@link
- * Lazy#get}. The following provision methods all request provision of the same type, but each
- * implies different semantics:
- *
- * <pre><code>
- *   SomeType getSomeType();
- *   {@literal Provider<SomeType>} getSomeTypeProvider();
- *   {@literal Lazy<SomeType>} getLazySomeType();
- * </code></pre>
- *
- * <a name="members-injection-methods"></a>
- * <h3>Members-injection methods</h3>
- *
- * <p>Members-injection methods have a single parameter and inject dependencies into each of the
- * {@link Inject}-annotated fields and methods of the passed instance. A members-injection method
- * may be void or return its single parameter as a convenience for chaining. The following are all
- * valid members-injection method declarations:
- *
- * <pre><code>
- *   void injectSomeType(SomeType someType);
- *   SomeType injectAndReturnSomeType(SomeType someType);
- * </code></pre>
- *
- * <p>A method with no parameters that returns a {@link MembersInjector} is equivalent to a members
- * injection method. Calling {@link MembersInjector#injectMembers} on the returned object will
- * perform the same work as a members injection method. For example:
- *
- * <pre><code>
- *   {@literal MembersInjector<SomeType>} getSomeTypeMembersInjector();
- * </code></pre>
- *
- * <h4>A note about covariance</h4>
- *
- * <p>While a members-injection method for a type will accept instances of its subtypes, only {@link
- * Inject}-annotated members of the parameter type and its supertypes will be injected; members of
- * subtypes will not. For example, given the following types, only {@code a} and {@code b} will be
- * injected into an instance of {@code Child} when it is passed to the members-injection method
- * {@code injectSelf(Self instance)}:
- *
- * <pre><code>
- *   class Parent {
- *     {@literal @}Inject A a;
- *   }
- *
- *   class Self extends Parent {
- *     {@literal @}Inject B b;
- *   }
- *
- *   class Child extends Self {
- *     {@literal @}Inject C c;
- *   }
- * </code></pre>
- *
- * <a name="instantiation"></a>
- * <h2>Instantiation</h2>
- *
- * <p>Component implementations are primarily instantiated via a generated <a
- * href="http://en.wikipedia.org/wiki/Builder_pattern">builder</a> or <a
- * href="https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)">factory</a>.
- *
- * <p>If a nested {@link Builder @Component.Builder} or {@link Factory @Component.Factory} type
- * exists in the component, Dagger will generate an implementation of that type. If neither exists,
- * Dagger will generate a builder type that has a method to set each of the {@linkplain #modules}
- * and component {@linkplain #dependencies} named with the <a
- * href="http://en.wikipedia.org/wiki/CamelCase">lower camel case</a> version of the module or
- * dependency type.
- *
- * <p>In either case, the Dagger-generated component type will have a static method, named either
- * {@code builder()} or {@code factory()}, that returns a builder or factory instance.
- *
- * <p>Example of using a builder:
- *
- * <pre>{@code
- *   public static void main(String[] args) {
- *     OtherComponent otherComponent = ...;
- *     MyComponent component = DaggerMyComponent.builder()
- *         // required because component dependencies must be set
- *         .otherComponent(otherComponent)
- *         // required because FlagsModule has constructor parameters
- *         .flagsModule(new FlagsModule(args))
- *         // may be elided because a no-args constructor is visible
- *         .myApplicationModule(new MyApplicationModule())
- *         .build();
- *   }
- * }</pre>
- *
- * <p>Example of using a factory:
- *
- * <pre>{@code
- * public static void main(String[] args) {
- *     OtherComponent otherComponent = ...;
- *     MyComponent component = DaggerMyComponent.factory()
- *         .create(otherComponent, new FlagsModule(args), new MyApplicationModule());
- *     // Note that all parameters to a factory method are required, even if one is for a module
- *     // that Dagger could instantiate. The only case where null is legal is for a
- *     // @BindsInstance @Nullable parameter.
- *   }
- * }</pre>
- *
- * <p>In the case that a component has no component dependencies and only no-arg modules, the
- * generated component will also have a factory method {@code create()}. {@code
- * SomeComponent.create()} and {@code SomeComponent.builder().build()} are both valid and
- * equivalent.
- *
- * <a name="scope"></a>
- * <h2>Scope</h2>
- *
- * <p>Each Dagger component can be associated with a scope by annotating it with the {@linkplain
- * Scope scope annotation}. The component implementation ensures that there is only one provision of
- * each scoped binding per instance of the component. If the component declares a scope, it may only
- * contain unscoped bindings or bindings of that scope anywhere in the graph. For example:
- *
- * <pre><code>
- *   {@literal @}Singleton {@literal @}Component
- *   interface MyApplicationComponent {
- *     // this component can only inject types using unscoped or {@literal @}Singleton bindings
- *   }
- * </code></pre>
- *
- * <p>In order to get the proper behavior associated with a scope annotation, it is the caller's
- * responsibility to instantiate new component instances when appropriate. A {@link Singleton}
- * component, for instance, should only be instantiated once per application, while a {@code
- * RequestScoped} component should be instantiated once per request. Because components are
- * self-contained implementations, exiting a scope is as simple as dropping all references to the
- * component instance.
- *
- * <a name="component-relationships"></a>
- * <h2>Component relationships</h2>
- *
- * <p>While there is much utility in isolated components with purely unscoped bindings, many
- * applications will call for multiple components with multiple scopes to interact. Dagger provides
- * two mechanisms for relating components.
- *
- * <a name="subcomponents"></a>
- * <h3>Subcomponents</h3>
- *
- * <p>The simplest way to relate two components is by declaring a {@link Subcomponent}. A
- * subcomponent behaves exactly like a component, but has its implementation generated within a
- * parent component or subcomponent. That relationship allows the subcomponent implementation to
- * inherit the <em>entire</em> binding graph from its parent when it is declared. For that reason, a
- * subcomponent isn't evaluated for completeness until it is associated with a parent.
- *
- * <p>Subcomponents are declared by listing the class in the {@link Module#subcomponents()}
- * attribute of one of the parent component's modules. This binds the {@link Subcomponent.Builder}
- * or {@link Subcomponent.Factory} for that subcomponent within the parent component.
- *
- * <p>Subcomponents may also be declared via a factory method on a parent component or subcomponent.
- * The method may have any name, but must return the subcomponent. The factory method's parameters
- * may be any number of the subcomponent's modules, but must at least include those without visible
- * no-arg constructors. The following is an example of a factory method that creates a
- * request-scoped subcomponent from a singleton-scoped parent:
- *
- * <pre><code>
- *   {@literal @}Singleton {@literal @}Component
- *   interface ApplicationComponent {
- *     // component methods...
- *
- *     RequestComponent newRequestComponent(RequestModule requestModule);
- *   }
- * </code></pre>
- *
- * <a name="component-dependencies"></a>
- * <h3>Component dependencies</h3>
- *
- * <p>While subcomponents are the simplest way to compose subgraphs of bindings, subcomponents are
- * tightly coupled with the parents; they may use any binding defined by their ancestor component
- * and subcomponents. As an alternative, components can use bindings only from another <em>component
- * interface</em> by declaring a {@linkplain #dependencies component dependency}. When a type is
- * used as a component dependency, each <a href="#provision-methods">provision method</a> on the
- * dependency is bound as a provider. Note that <em>only</em> the bindings exposed as provision
- * methods are available through component dependencies.
- *
- * @since 2.0
- */
-@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-@Target(TYPE)
-@Documented
-public @interface Component {
-  /**
-   * A list of classes annotated with {@link Module} whose bindings are used to generate the
-   * component implementation. Note that through the use of {@link Module#includes} the full set of
-   * modules used to implement the component may include more modules that just those listed here.
-   */
-  Class<?>[] modules() default {};
-
-  /**
-   * A list of types that are to be used as <a href="#component-dependencies">component
-   * dependencies</a>.
-   */
-  Class<?>[] dependencies() default {};
-
-  /**
-   * A builder for a component.
-   *
-   * <p>A builder is a type with setter methods for the {@linkplain Component#modules modules},
-   * {@linkplain Component#dependencies dependencies} and {@linkplain BindsInstance bound instances}
-   * required by the component and a single no-argument build method that creates a new component
-   * instance.
-   *
-   * <p>Components may have a single nested {@code static abstract class} or {@code interface}
-   * annotated with {@code @Component.Builder}. If they do, then Dagger will generate a builder
-   * class that implements that type. Note that a component with a {@code @Component.Builder} may
-   * not also have a {@code @Component.Factory}.
-   *
-   * <p>Builder types must follow some rules:
-   *
-   * <ul>
-   *   <li>There <i>must</i> be exactly one abstract no-argument method that returns the component
-   *       type or one of its supertypes, called the "build method".
-   *   <li>There <i>may</i> be other other abstract methods, called "setter methods".
-   *   <li>Setter methods <i>must</i> take a single argument and return {@code void}, the builder
-   *       type or a supertype of the builder type.
-   *   <li>There <i>must</i> be a setter method for each {@linkplain Component#dependencies
-   *       component dependency}.
-   *   <li>There <i>must</i> be a setter method for each non-{@code abstract} {@linkplain
-   *       Component#modules module} that has non-{@code static} binding methods, unless Dagger can
-   *       instantiate that module with a visible no-argument constructor.
-   *   <li>There <i>may</i> be setter methods for modules that Dagger can instantiate or does not
-   *       need to instantiate.
-   *   <li>There <i>may</i> be setter methods annotated with {@code @BindsInstance}. These methods
-   *       bind the instance passed to them within the component. See {@link
-   *       BindsInstance @BindsInstance} for more information.
-   *   <li>There <i>may</i> be non-{@code abstract} methods, but they are ignored as far as
-   *       validation and builder generation are concerned.
-   * </ul>
-   *
-   * For example, this could be a valid {@code Component} with a {@code Builder}:
-   *
-   * <pre><code>
-   * {@literal @}Component(modules = {BackendModule.class, FrontendModule.class})
-   * interface MyComponent {
-   *   MyWidget myWidget();
-   *
-   *   {@literal @}Component.Builder
-   *   interface Builder {
-   *     Builder backendModule(BackendModule bm);
-   *     Builder frontendModule(FrontendModule fm);
-   *     {@literal @}BindsInstance
-   *     Builder foo(Foo foo);
-   *     MyComponent build();
-   *   }
-   * }</code></pre>
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Builder {}
-
-  /**
-   * A factory for a component.
-   *
-   * <p>A factory is a type with a single method that returns a new component instance each time it
-   * is called. The parameters of that method allow the caller to provide the {@linkplain
-   * Component#modules modules}, {@linkplain Component#dependencies dependencies} and {@linkplain
-   * BindsInstance bound instances} required by the component.
-   *
-   * <p>Components may have a single nested {@code static abstract class} or {@code interface}
-   * annotated with {@code @Component.Factory}. If they do, then Dagger will generate a factory
-   * class that will implement that type. Note that a component with a {@code @Component.Factory}
-   * may not also have a {@code @Component.Builder}.
-   *
-   * <p>Factory types must follow some rules:
-   *
-   * <ul>
-   *   <li>There <i>must</i> be exactly one abstract method, which must return the component type or
-   *       one of its supertypes.
-   *   <li>The method <i>must</i> have a parameter for each {@linkplain Component#dependencies
-   *       component dependency}.
-   *   <li>The method <i>must</i> have a parameter for each non-{@code abstract} {@linkplain
-   *       Component#modules module} that has non-{@code static} binding methods, unless Dagger can
-   *       instantiate that module with a visible no-argument constructor.
-   *   <li>The method <i>may</i> have parameters for modules that Dagger can instantiate or does not
-   *       need to instantiate.
-   *   <li>The method <i>may</i> have parameters annotated with {@code @BindsInstance}. These
-   *       parameters bind the instance passed for that parameter within the component. See {@link
-   *       BindsInstance @BindsInstance} for more information.
-   *   <li>There <i>may</i> be non-{@code abstract} methods, but they are ignored as far as
-   *       validation and factory generation are concerned.
-   * </ul>
-   *
-   * For example, this could be a valid {@code Component} with a {@code Factory}:
-   *
-   * <pre><code>
-   * {@literal @}Component(modules = {BackendModule.class, FrontendModule.class})
-   * interface MyComponent {
-   *   MyWidget myWidget();
-   *
-   *   {@literal @}Component.Factory
-   *   interface Factory {
-   *     MyComponent newMyComponent(
-   *         BackendModule bm, FrontendModule fm, {@literal @}BindsInstance Foo foo);
-   *   }
-   * }</code></pre>
-   *
-   * <p>For a root component, if a {@code @Component.Factory} is defined, the generated component
-   * type will have a {@code static} method named {@code factory()} that returns an instance of that
-   * factory.
-   *
-   * @since 2.22
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Factory {}
-}
diff --git a/java/dagger/Lazy.java b/java/dagger/Lazy.java
deleted file mode 100644
index d4408fa..0000000
--- a/java/dagger/Lazy.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-/**
- * A handle to a lazily-computed value. Each {@code Lazy} computes its value on
- * the first call to {@link #get()} and remembers that same value for all
- * subsequent calls to {@code get()}.
- *
- * <p>All implementations are expected to be thread-safe and compute their value at most once.
- *
- * <h2>Example</h2>
- * The differences between <strong>direct injection</strong>, <strong>provider
- * injection</strong> and <strong>lazy injection</strong> are best demonstrated
- * with an example. Start with a module that computes a different integer for
- * each use:<pre><code>
- *   {@literal @Module}
- *   final class CounterModule {
- *     int next = 100;
- *
- *     {@literal @Provides} Integer provideInteger() {
- *       System.out.println("computing...");
- *       return next++;
- *     }
- *   }
- * </code></pre>
- *
- * <h3>Direct Injection</h3>
- * This class injects that integer and prints it 3 times:<pre><code>
- *   final class DirectCounter {
- *     {@literal @Inject} Integer value;
- *
- *     void print() {
- *       System.out.println("printing...");
- *       System.out.println(value);
- *       System.out.println(value);
- *       System.out.println(value);
- *     }
- *   }
- * </code></pre>
- * Injecting a {@code DirectCounter} and invoking {@code print()} reveals that
- * the value is computed <i>before</i> it is required:<pre><code>
- *   computing...
- *   printing...
- *   100
- *   100
- *   100
- * </code></pre>
- *
- * <h3>Provider Injection</h3>
- * This class injects a {@linkplain javax.inject.Provider provider} for the
- * integer. It calls {@code Provider.get()} 3 times and prints each result:
- * <pre><code>
- *   final class ProviderCounter {
- *     {@literal @Inject Provider<Integer> provider;}
- *
- *     void print() {
- *       System.out.println("printing...");
- *       System.out.println(provider.get());
- *       System.out.println(provider.get());
- *       System.out.println(provider.get());
- *     }
- *   }
- * </code></pre>
- * Injecting a {@code ProviderCounter} and invoking {@code print()} shows that
- * a new value is computed each time {@code Provider.get()} is used:<pre><code>
- *   printing...
- *   computing...
- *   100
- *   computing...
- *   101
- *   computing...
- *   102
- * </code></pre>
- *
- * <h3>Lazy Injection</h3>
- * This class injects a {@code Lazy} for the integer. Like the provider above,
- * it calls {@code Lazy.get()} 3 times and prints each result:<pre><code>
- *   final class LazyCounter {
- *     {@literal @Inject Lazy<Integer> lazy;}
- *
- *     void print() {
- *       System.out.println("printing...");
- *       System.out.println(lazy.get());
- *       System.out.println(lazy.get());
- *       System.out.println(lazy.get());
- *     }
- *   }
- * </code></pre>
- * Injecting a {@code LazyCounter} and invoking {@code print()} shows that a new
- * value is computed immediately before it is needed. The same value is returned
- * for all subsequent uses:<pre><code>
- *   printing...
- *   computing...
- *   100
- *   100
- *   100
- * </code></pre>
- *
- * <h3>Lazy != Singleton</h3>
- * Note that each injected {@code Lazy} is independent, and remembers its value
- * in isolation of other {@code Lazy} instances. In this example, two {@code
- * LazyCounter} objects are created and {@code print()} is called on each:
- * <pre><code>
- *   final class LazyCounters {
- *     {@literal @Inject} LazyCounter counter1;
- *     {@literal @Inject} LazyCounter counter2;
- *
- *     void print() {
- *       counter1.print();
- *       counter2.print();
- *     }
- *   }
- * </code></pre>
- * The output demonstrates that each {@code Lazy} works independently:
- * <pre><code>
- *   printing...
- *   computing...
- *   100
- *   100
- *   100
- *   printing...
- *   computing...
- *   101
- *   101
- *   101
- * </code></pre>
- * Use {@link javax.inject.Singleton @Singleton} to share one instance among all
- * clients, and {@code Lazy} for lazy computation in a single client.
- */
-public interface Lazy<T> {
-  /**
-   * Return the underlying value, computing the value if necessary. All calls to
-   * the same {@code Lazy} instance will return the same result.
-   */
-  T get();
-}
diff --git a/java/dagger/MapKey.java b/java/dagger/MapKey.java
deleted file mode 100644
index 46dbf93..0000000
--- a/java/dagger/MapKey.java
+++ /dev/null
@@ -1,116 +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;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.util.Map;
-
-/**
- * Identifies annotation types that are used to associate keys with values returned by {@linkplain
- * Provides provider methods} in order to compose a {@linkplain dagger.multibindings.IntoMap map}.
- *
- * <p>Every provider method annotated with {@code @Provides} and {@code @IntoMap} must also have an
- * annotation that identifies the key for that map entry. That annotation's type must be annotated
- * with {@code @MapKey}.
- *
- * <p>Typically, the key annotation has a single member, whose value is used as the map key.
- *
- * <p>For example, to add an entry to a {@code Map<SomeEnum, Integer>} with key {@code
- * SomeEnum.FOO}, you could use an annotation called {@code @SomeEnumKey}:
- *
- * <pre><code>
- * {@literal @}MapKey
- * {@literal @}interface SomeEnumKey {
- *   SomeEnum value();
- * }
- *
- * {@literal @}Module
- * class SomeModule {
- *   {@literal @}Provides
- *   {@literal @}IntoMap
- *   {@literal @}SomeEnumKey(SomeEnum.FOO)
- *   Integer provideFooValue() {
- *     return 2;
- *   }
- * }
- *
- * class SomeInjectedType {
- *   {@literal @}Inject
- *   SomeInjectedType({@literal Map<SomeEnum, Integer>} map) {
- *     assert map.get(SomeEnum.FOO) == 2;
- *   }
- * }
- * </code></pre>
- *
- * <p>If {@code unwrapValue} is true, the annotation's single member can be any type except an
- * array.
- *
- * <p>See {@link dagger.multibindings} for standard unwrapped map key annotations for keys that are
- * boxed primitives, strings, or classes.
- *
- * <h2>Annotations as keys</h2>
- *
- * <p>If {@link #unwrapValue} is false, then the annotation itself is used as the map key. For
- * example, to add an entry to a {@code Map<MyMapKey, Integer>} map:
- *
- * <pre><code>
- * {@literal @}MapKey(unwrapValue = false)
- * {@literal @}interface MyMapKey {
- *   String someString();
- *   MyEnum someEnum();
- * }
- *
- * {@literal @}Module
- * class SomeModule {
- *   {@literal @}Provides
- *   {@literal @}IntoMap
- *   {@literal @}MyMapKey(someString = "foo", someEnum = BAR)
- *   Integer provideFooBarValue() {
- *     return 2;
- *   }
- * }
- *
- * class SomeInjectedType {
- *   {@literal @}Inject
- *   SomeInjectedType({@literal Map<MyMapKey, Integer>} map) {
- *     assert map.get(new MyMapKeyImpl("foo", MyEnum.BAR)) == 2;
- *   }
- * }
- * </code></pre>
- *
- * <p>(Note that there must be a class {@code MyMapKeyImpl} that implements {@code MyMapKey} in
- * order to call {@link Map#get(Object)} on the provided map.)
- *
- * @see <a href="https://dagger.dev/multibindings#map-multibindings">Map multibinding</a>
- */
-@Documented
-@Target(ANNOTATION_TYPE)
-@Retention(RUNTIME)
-public @interface MapKey {
-  /**
-   * True to use the value of the single member of the annotated annotation as the map key; false
-   * to use the annotation instance as the map key.
-   *
-   * <p>If true, the single member must not be an array.
-   */
-  boolean unwrapValue() default true;
-}
diff --git a/java/dagger/MembersInjector.java b/java/dagger/MembersInjector.java
deleted file mode 100644
index 5e83889..0000000
--- a/java/dagger/MembersInjector.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-/**
- * Injects dependencies into the fields and methods on instances of type {@code T}. Ignores the
- * presence or absence of an injectable constructor.
- *
- * @param <T> type to inject members of
- *
- * @since 2.0 (since 1.0 without the provision that {@link #injectMembers} cannot accept
- *      {@code null})
- */
-public interface MembersInjector<T> {
-
-  /**
-   * Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
-   * absence of an injectable constructor.
-   *
-   * <p>Whenever a {@link Component} creates an instance, it performs this injection automatically
-   * (after first performing constructor injection), so if you're able to let the component create
-   * all your objects for you, you'll never need to use this method.
-   *
-   * @param instance into which members are to be injected
-   * @throws NullPointerException if {@code instance} is {@code null}
-   */
-  void injectMembers(T instance);
-}
diff --git a/java/dagger/Module.java b/java/dagger/Module.java
deleted file mode 100644
index bd32a1f..0000000
--- a/java/dagger/Module.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotates a class that contributes to the object graph.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Module {
-  /**
-   * Additional {@code @Module}-annotated classes from which this module is
-   * composed. The de-duplicated contributions of the modules in
-   * {@code includes}, and of their inclusions recursively, are all contributed
-   * to the object graph.
-   */
-  Class<?>[] includes() default {};
-
-  /**
-   * Any {@link Subcomponent}- or {@code @ProductionSubcomponent}-annotated classes which should be
-   * children of the component in which this module is installed. A subcomponent may be listed in
-   * more than one module in a component.
-   *
-   * @since 2.7
-   */
-  @Beta
-  Class<?>[] subcomponents() default {};
-}
diff --git a/java/dagger/Provides.java b/java/dagger/Provides.java
deleted file mode 100644
index a60be3b..0000000
--- a/java/dagger/Provides.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates methods of a {@linkplain Module module} to create a provider method binding. The
- * method's return type is bound to its returned value. The {@linkplain Component component}
- * implementation will pass dependencies to the method as parameters.
- *
- * <h3>Nullability</h3>
- *
- * <p>Dagger forbids injecting {@code null} by default. Component implemenations that invoke
- * {@code @Provides} methods that return {@code null} will throw a {@link NullPointerException}
- * immediately thereafter. {@code @Provides} methods may opt into allowing {@code null} by
- * annotating the method with any {@code @Nullable} annotation like
- * {@code javax.annotation.Nullable} or {@code android.support.annotation.Nullable}.
- *
- * <p>If a {@code @Provides} method is marked {@code @Nullable}, Dagger will <em>only</em>
- * allow injection into sites that are marked {@code @Nullable} as well. A component that
- * attempts to pair a {@code @Nullable} provision with a non-{@code @Nullable} injection site
- * will fail to compile.
- */
-@Documented @Target(METHOD) @Retention(RUNTIME)
-public @interface Provides {
-}
diff --git a/java/dagger/Reusable.java b/java/dagger/Reusable.java
deleted file mode 100644
index 2cb68aa..0000000
--- a/java/dagger/Reusable.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-/**
- * A scope that indicates that the object returned by a binding may be (but might not be) reused.
- *
- * <p>{@code @Reusable} is useful when you want to limit the number of provisions of a type, but
- * there is no specific lifetime over which there must be only one instance.
- *
- * @see <a href="https://dagger.dev/users-guide#reusable-scope">Reusable Scope</a>
- */
-@Documented
-@Beta
-@Retention(RUNTIME)
-@Scope
-public @interface Reusable {}
diff --git a/java/dagger/Subcomponent.java b/java/dagger/Subcomponent.java
deleted file mode 100644
index 2bf087f..0000000
--- a/java/dagger/Subcomponent.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * A subcomponent that inherits the bindings from a parent {@link Component} or
- * {@link Subcomponent}. The details of how to associate a subcomponent with a parent are described
- * in the documentation for {@link Component}.
- *
- * @since 2.0
- */
-@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-@Target(TYPE)
-@Documented
-public @interface Subcomponent {
-  /**
-   * A list of classes annotated with {@link Module} whose bindings are used to generate the
-   * subcomponent implementation.  Note that through the use of {@link Module#includes} the full set
-   * of modules used to implement the subcomponent may include more modules that just those listed
-   * here.
-   */
-  Class<?>[] modules() default {};
-
-  /**
-   * A builder for a subcomponent.
-   *
-   * <p>This follows all the rules of {@link Component.Builder}, except it must appear in classes
-   * annotated with {@link Subcomponent} instead of {@code Component}.
-   *
-   * <p>If a subcomponent defines a builder, its parent component(s) will have a binding for that
-   * builder type, allowing an instance or {@code Provider} of that builder to be injected or
-   * returned from a method on that component like any other binding.
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Builder {}
-
-  /**
-   * A factory for a subcomponent.
-   *
-   * <p>This follows all the rules of {@link Component.Factory}, except it must appear in classes
-   * annotated with {@link Subcomponent} instead of {@code Component}.
-   *
-   * <p>If a subcomponent defines a factory, its parent component(s) will have a binding for that
-   * factory type, allowing an instance of that factory to be injected or returned from a method on
-   * that component like any other binding.
-   *
-   * @since 2.22
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Factory {}
-}
diff --git a/java/dagger/android/AndroidInjection.java b/java/dagger/android/AndroidInjection.java
deleted file mode 100644
index 2f4fb4c..0000000
--- a/java/dagger/android/AndroidInjection.java
+++ /dev/null
@@ -1,233 +0,0 @@
-  /*
- * Copyright (C) 2017 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.android;
-
-import static android.util.Log.DEBUG;
-import static dagger.internal.Preconditions.checkNotNull;
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.Fragment;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
-import android.content.Context;
-import android.util.Log;
-import dagger.internal.Beta;
-
-/** Injects core Android types. */
-@Beta
-public final class AndroidInjection {
-  private static final String TAG = "dagger.android";
-
-  /**
-   * Injects {@code activity} if an associated {@link AndroidInjector} implementation can be found,
-   * otherwise throws an {@link IllegalArgumentException}.
-   *
-   * @throws RuntimeException if the {@link Application} doesn't implement {@link
-   *     HasAndroidInjector} or {@link HasActivityInjector}.
-   */
-  public static void inject(Activity activity) {
-    checkNotNull(activity, "activity");
-    Application application = activity.getApplication();
-    AndroidInjector<? super Activity> injector;
-    if (application instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) application).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", application.getClass());
-    } else if (application instanceof HasActivityInjector) {
-      injector = ((HasActivityInjector) application).activityInjector();
-      checkNotNull(injector, "%s.activityInjector() returned null", application.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              application.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasActivityInjector.class.getCanonicalName()));
-    }
-
-    injector.inject(activity);
-  }
-
-  /**
-   * Injects {@code fragment} if an associated {@link AndroidInjector} implementation can be found,
-   * otherwise throws an {@link IllegalArgumentException}.
-   *
-   * <p>Uses the following algorithm to find the appropriate {@link AndroidInjector} to use to
-   * inject {@code fragment}:
-   *
-   * <ol>
-   *   <li>Walks the parent-fragment hierarchy to find a fragment that implements {@link
-   *       HasAndroidInjector} or {@link HasFragmentInjector}, and if none do
-   *   <li>Uses the {@code fragment}'s {@link Fragment#getActivity() activity} if it implements
-   *       {@link HasAndroidInjector} or {@link HasFragmentInjector}, and if not
-   *   <li>Uses the {@link android.app.Application} if it implements {@link HasAndroidInjector}
-   *       {@link HasFragmentInjector}.
-   * </ol>
-   *
-   * If none of them implement {@link HasAndroidInjector} or {@link HasFragmentInjector}, a {@link
-   * IllegalArgumentException} is thrown.
-   *
-   * @throws IllegalArgumentException if no parent fragment, activity, or application implements
-   *     {@link HasAndroidInjector} or {@link HasFragmentInjector}.
-   */
-  public static void inject(Fragment fragment) {
-    checkNotNull(fragment, "fragment");
-
-    Object hasInjector = findHasFragmentInjector(fragment);
-    AndroidInjector<? super Fragment> injector;
-    if (hasInjector instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) hasInjector).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", hasInjector.getClass());
-    } else if (hasInjector instanceof HasFragmentInjector) {
-      injector = ((HasFragmentInjector) hasInjector).fragmentInjector();
-      checkNotNull(injector, "%s.fragmentInjector() returned null", hasInjector.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              hasInjector.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasFragmentInjector.class.getCanonicalName()));
-    }
-
-    if (Log.isLoggable(TAG, DEBUG)) {
-      Log.d(
-          TAG,
-          String.format(
-              "An injector for %s was found in %s",
-              fragment.getClass().getCanonicalName(),
-              hasInjector.getClass().getCanonicalName()));
-    }
-
-    injector.inject(fragment);
-  }
-
-  private static Object findHasFragmentInjector(Fragment fragment) {
-    Fragment parentFragment = fragment;
-    while ((parentFragment = parentFragment.getParentFragment()) != null) {
-      if (parentFragment instanceof HasAndroidInjector
-          || parentFragment instanceof HasFragmentInjector) {
-        return parentFragment;
-      }
-    }
-    Activity activity = fragment.getActivity();
-    if (activity instanceof HasAndroidInjector || activity instanceof HasFragmentInjector) {
-      return activity;
-    }
-    Application application = activity.getApplication();
-    if (application instanceof HasAndroidInjector || application instanceof HasFragmentInjector) {
-      return application;
-    }
-    throw new IllegalArgumentException(
-        String.format("No injector was found for %s", fragment.getClass().getCanonicalName()));
-  }
-
-  /**
-   * Injects {@code service} if an associated {@link AndroidInjector} implementation can be found,
-   * otherwise throws an {@link IllegalArgumentException}.
-   *
-   * @throws RuntimeException if the {@link Application} doesn't implement {@link
-   *     HasAndroidInjector} or {@link HasServiceInjector}.
-   */
-  public static void inject(Service service) {
-    checkNotNull(service, "service");
-    Application application = service.getApplication();
-    AndroidInjector<? super Service> injector;
-    if (application instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) application).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", application.getClass());
-    } else if (application instanceof HasServiceInjector) {
-      injector = ((HasServiceInjector) application).serviceInjector();
-      checkNotNull(injector, "%s.serviceInjector() returned null", application.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              application.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasServiceInjector.class.getCanonicalName()));
-    }
-
-    injector.inject(service);
-  }
-
-  /**
-   * Injects {@code broadcastReceiver} if an associated {@link AndroidInjector} implementation can
-   * be found, otherwise throws an {@link IllegalArgumentException}.
-   *
-   * @throws RuntimeException if the {@link Application} from {@link
-   *     Context#getApplicationContext()} doesn't implement {@link HasAndroidInjector} or {@link
-   *     HasBroadcastReceiverInjector}.
-   */
-  public static void inject(BroadcastReceiver broadcastReceiver, Context context) {
-    checkNotNull(broadcastReceiver, "broadcastReceiver");
-    checkNotNull(context, "context");
-
-    Application application = (Application) context.getApplicationContext();
-    AndroidInjector<? super BroadcastReceiver> injector;
-    if (application instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) application).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", application.getClass());
-    } else if (application instanceof HasBroadcastReceiverInjector) {
-      injector = ((HasBroadcastReceiverInjector) application).broadcastReceiverInjector();
-      checkNotNull(
-          injector, "%s.broadcastReceiverInjector() returned null", application.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              application.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasBroadcastReceiverInjector.class.getCanonicalName()));
-    }
-
-    injector.inject(broadcastReceiver);
-  }
-
-  /**
-   * Injects {@code contentProvider} if an associated {@link AndroidInjector} implementation can be
-   * found, otherwise throws an {@link IllegalArgumentException}.
-   *
-   * @throws RuntimeException if the {@link Application} doesn't implement {@link
-   *     HasAndroidInjector} or {@link HasContentProviderInjector}.
-   */
-  public static void inject(ContentProvider contentProvider) {
-    checkNotNull(contentProvider, "contentProvider");
-    Application application = (Application) contentProvider.getContext().getApplicationContext();
-
-    AndroidInjector<? super ContentProvider> injector;
-    if (application instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) application).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", application.getClass());
-    } else if (application instanceof HasContentProviderInjector) {
-      injector = ((HasContentProviderInjector) application).contentProviderInjector();
-      checkNotNull(injector, "%s.contentProviderInjector() returned null", application.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              application.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasBroadcastReceiverInjector.class.getCanonicalName()));
-    }
-
-    injector.inject(contentProvider);
-  }
-
-  private AndroidInjection() {}
-}
diff --git a/java/dagger/android/AndroidInjectionKey.java b/java/dagger/android/AndroidInjectionKey.java
deleted file mode 100644
index d4a5d72..0000000
--- a/java/dagger/android/AndroidInjectionKey.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2018 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.android;
-
-import static java.lang.annotation.ElementType.METHOD;
-
-import dagger.MapKey;
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Target;
-
-/**
- * {@link MapKey} annotation to key {@link AndroidInjector.Factory} bindings. The {@linkplain
- * #value() value} of the annotation is the canonical name of the class that will be passed to
- * {@link AndroidInjector#inject(Object)}.
- *
- * <p>All key strings will be obfuscated by ProGuard/R8/AppReduce if the named class is obfuscated.
- *
- * <p>
- * You should only use this annotation if you are using a version of ProGuard/R8/AppReduce that
- * supports the {@code -identifiernamestring} flag.
- */
-@Beta
-@MapKey
-@Target(METHOD)
-@Documented
-public @interface AndroidInjectionKey {
-  /** The fully qualified class name of the type to be injected. */
-  String value();
-}
diff --git a/java/dagger/android/AndroidInjectionModule.java b/java/dagger/android/AndroidInjectionModule.java
deleted file mode 100644
index 4e496f8..0000000
--- a/java/dagger/android/AndroidInjectionModule.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import dagger.Module;
-import dagger.internal.Beta;
-import dagger.multibindings.Multibinds;
-import java.util.Map;
-
-/**
- * Contains bindings to ensure the usability of {@code dagger.android} framework classes. This
- * module should be installed in the component that is used to inject the {@link
- * android.app.Application} class.
- */
-@Beta
-@Module
-public abstract class AndroidInjectionModule {
-  @Multibinds
-  abstract Map<Class<?>, AndroidInjector.Factory<?>> classKeyedInjectorFactories();
-
-  @Multibinds
-  abstract Map<String, AndroidInjector.Factory<?>> stringKeyedInjectorFactories();
-
-  private AndroidInjectionModule() {}
-}
diff --git a/java/dagger/android/AndroidInjector.java b/java/dagger/android/AndroidInjector.java
deleted file mode 100644
index d2b9dec..0000000
--- a/java/dagger/android/AndroidInjector.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import dagger.BindsInstance;
-import dagger.internal.Beta;
-
-/**
- * Performs members-injection for a concrete subtype of a <a
- * href="https://developer.android.com/guide/components/">core Android type</a> (e.g., {@link
- * android.app.Activity} or {@link android.app.Fragment}).
- *
- * <p>Commonly implemented by {@link dagger.Subcomponent}-annotated types whose {@link
- * dagger.Subcomponent.Factory} extends {@link Factory}.
- *
- * @param <T> a concrete subtype of a core Android type
- * @see AndroidInjection
- * @see DispatchingAndroidInjector
- * @see ContributesAndroidInjector
- */
-@Beta
-public interface AndroidInjector<T> {
-
-  /** Injects the members of {@code instance}. */
-  void inject(T instance);
-
-  /**
-   * Creates {@link AndroidInjector}s for a concrete subtype of a core Android type.
-   *
-   * @param <T> the concrete type to be injected
-   */
-  interface Factory<T> {
-    /**
-     * Creates an {@link AndroidInjector} for {@code instance}. This should be the same instance
-     * that will be passed to {@link #inject(Object)}.
-     */
-    AndroidInjector<T> create(@BindsInstance T instance);
-  }
-
-  /**
-   * An adapter that lets the common {@link dagger.Subcomponent.Builder} pattern implement {@link
-   * Factory}.
-   *
-   * @param <T> the concrete type to be injected
-   * @deprecated Prefer {@link Factory} now that components can have {@link dagger.Component.Factory
-   *     factories} instead of builders
-   */
-  @Deprecated
-  abstract class Builder<T> implements AndroidInjector.Factory<T> {
-    @Override
-    public final AndroidInjector<T> create(T instance) {
-      seedInstance(instance);
-      return build();
-    }
-
-    /**
-     * Provides {@code instance} to be used in the binding graph of the built {@link
-     * AndroidInjector}. By default, this is used as a {@link BindsInstance} method, but it may be
-     * overridden to provide any modules which need a reference to the activity.
-     *
-     * <p>This should be the same instance that will be passed to {@link #inject(Object)}.
-     */
-    @BindsInstance
-    public abstract void seedInstance(T instance);
-
-    /** Returns a newly-constructed {@link AndroidInjector}. */
-    public abstract AndroidInjector<T> build();
-  }
-}
diff --git a/java/dagger/android/AndroidManifest.xml b/java/dagger/android/AndroidManifest.xml
deleted file mode 100644
index f071b60..0000000
--- a/java/dagger/android/AndroidManifest.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
- Copyright (C) 2016 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="dagger.android">
-  <uses-sdk android:minSdkVersion="14" />
-</manifest>
diff --git a/java/dagger/android/BUILD b/java/dagger/android/BUILD
deleted file mode 100644
index a88d16e..0000000
--- a/java/dagger/android/BUILD
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Public Dagger API for Android
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-    "SOURCE_7_TARGET_7",
-)
-load("//tools:maven.bzl", "POM_VERSION", "pom_file")
-
-# Work around b/70476182 which prevents Kythe from connecting :producers to the .java files it
-# contains.
-SRCS = glob([
-    "*.java",
-    "internal/*.java",
-])
-
-filegroup(
-    name = "android-srcs",
-    srcs = SRCS,
-)
-
-android_library(
-    name = "android",
-    srcs = SRCS,
-    javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    manifest = "AndroidManifest.xml",
-    proguard_specs = ["proguard.cfg"],
-    tags = ["maven_coordinates=com.google.dagger:dagger-android:" + POM_VERSION],
-    deps = [
-        ":manual-maven-deps",
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-    ],
-)
-
-# Our pom.xml generator does not have a way to add manual maven deps. This target exports the
-# targets that don't have the necessary maven_coordinates tags.
-android_library(
-    name = "manual-maven-deps",
-    tags = ["maven_coordinates=com.android.support:support-annotations:25.0.0"],
-    visibility = ["//visibility:private"],
-    exports = [
-        "@androidsdk//com.android.support:support-annotations-25.0.0",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-android",
-    artifact_name = "Dagger Android",
-    packaging = "aar",
-    targets = [":android"],
-)
-
-# b/37741866 and https://github.com/google/dagger/issues/715
-pom_file(
-    name = "jarimpl-pom",
-    artifact_id = "dagger-android-jarimpl",
-    artifact_name = "Dagger Android",
-    targets = [":android"],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "android-javadoc",
-    srcs = [":android-srcs"],
-    android_api_level = 26,
-    exclude_packages = ["dagger.android.internal"],
-    root_packages = ["dagger.android"],
-    deps = [":android"],
-)
diff --git a/java/dagger/android/ContributesAndroidInjector.java b/java/dagger/android/ContributesAndroidInjector.java
deleted file mode 100644
index 5aa9312..0000000
--- a/java/dagger/android/ContributesAndroidInjector.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Generates an {@link AndroidInjector} for the return type of this method. The injector is
- * implemented with a {@link dagger.Subcomponent} and will be a child of the {@link dagger.Module}'s
- * component.
- *
- * <p>This annotation must be applied to an abstract method in a {@link dagger.Module} that returns
- * a concrete Android framework type (e.g. {@code FooActivity}, {@code BarFragment}, {@code
- * MyService}, etc). The method should have no parameters.
- *
- * <p>For more information, see <a href="https://dagger.dev/android">the docs</a>
- */
-@Documented
-@Retention(RUNTIME)
-@Target(METHOD)
-public @interface ContributesAndroidInjector {
-  /** Modules to be installed in the generated {@link dagger.Subcomponent}. */
-  Class<?>[] modules() default {};
-}
diff --git a/java/dagger/android/DaggerActivity.java b/java/dagger/android/DaggerActivity.java
deleted file mode 100644
index 43708f3..0000000
--- a/java/dagger/android/DaggerActivity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * An {@link Activity} that injects its members in {@link #onCreate(Bundle)} and can be used to
- * inject {@link Fragment}s attached to it.
- */
-@Beta
-public abstract class DaggerActivity extends Activity implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  protected void onCreate(@Nullable Bundle savedInstanceState) {
-    AndroidInjection.inject(this);
-    super.onCreate(savedInstanceState);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/DaggerApplication.java b/java/dagger/android/DaggerApplication.java
deleted file mode 100644
index d09050b..0000000
--- a/java/dagger/android/DaggerApplication.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import android.app.Application;
-import android.content.ContentProvider;
-import com.google.errorprone.annotations.ForOverride;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * An {@link Application} that injects its members and can be used to inject objects that the
- * Android framework instantiates, such as Activitys, Fragments, or Services. Injection is performed
- * in {@link #onCreate()} or the first call to {@link AndroidInjection#inject(ContentProvider)},
- * whichever happens first.
- */
-@Beta
-public abstract class DaggerApplication extends Application implements HasAndroidInjector {
-  @Inject volatile DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onCreate() {
-    super.onCreate();
-    injectIfNecessary();
-  }
-
-  /**
-   * Implementations should return an {@link AndroidInjector} for the concrete {@link
-   * DaggerApplication}. Typically, that injector is a {@link dagger.Component}.
-   */
-  @ForOverride
-  protected abstract AndroidInjector<? extends DaggerApplication> applicationInjector();
-
-  /**
-   * Lazily injects the {@link DaggerApplication}'s members. Injection cannot be performed in {@link
-   * Application#onCreate()} since {@link android.content.ContentProvider}s' {@link
-   * android.content.ContentProvider#onCreate() onCreate()} method will be called first and might
-   * need injected members on the application. Injection is not performed in the constructor, as
-   * that may result in members-injection methods being called before the constructor has completed,
-   * allowing for a partially-constructed instance to escape.
-   */
-  private void injectIfNecessary() {
-    if (androidInjector == null) {
-      synchronized (this) {
-        if (androidInjector == null) {
-          @SuppressWarnings("unchecked")
-          AndroidInjector<DaggerApplication> applicationInjector =
-              (AndroidInjector<DaggerApplication>) applicationInjector();
-          applicationInjector.inject(this);
-          if (androidInjector == null) {
-            throw new IllegalStateException(
-                "The AndroidInjector returned from applicationInjector() did not inject the "
-                    + "DaggerApplication");
-          }
-        }
-      }
-    }
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    // injectIfNecessary should already be called unless we are about to inject a ContentProvider,
-    // which can happen before Application.onCreate()
-    injectIfNecessary();
-
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/DaggerBroadcastReceiver.java b/java/dagger/android/DaggerBroadcastReceiver.java
deleted file mode 100644
index d39aa86..0000000
--- a/java/dagger/android/DaggerBroadcastReceiver.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.support.annotation.CallSuper;
-import dagger.internal.Beta;
-
-/**
- * A {@link BroadcastReceiver} that injects its members in every call to {@link #onReceive(Context,
- * Intent)}.
- *
- * <p>This class should only be used for {@link BroadcastReceiver}s that are declared in an {@code
- * AndroidManifest.xml}. If, instead, the {@link BroadcastReceiver} is created in code, prefer
- * constructor injection.
- *
- * <p>Note: this class is <em>not thread safe</em> and should not be used with multiple {@link
- * android.os.Handler}s in calls to {@link Context#registerReceiver(BroadcastReceiver,
- * android.content.IntentFilter, String, android.os.Handler)}. Injection is performed on each
- * invocation to {@link #onReceive(Context, Intent)} which could result in inconsistent views of
- * injected dependencies across threads.
- *
- * <p>Subclasses should override {@link #onReceive(Context, Intent)} and call {@code
- * super.onReceive(context, intent)} immediately to ensure injection is performed immediately.
- */
-@Beta
-public abstract class DaggerBroadcastReceiver extends BroadcastReceiver {
-  @CallSuper
-  @Override
-  public void onReceive(Context context, Intent intent) {
-    AndroidInjection.inject(this, context);
-  }
-}
diff --git a/java/dagger/android/DaggerContentProvider.java b/java/dagger/android/DaggerContentProvider.java
deleted file mode 100644
index 4aad485..0000000
--- a/java/dagger/android/DaggerContentProvider.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import android.content.ContentProvider;
-import android.support.annotation.CallSuper;
-import dagger.internal.Beta;
-
-/** A {@link ContentProvider} that injects its members in {@link #onCreate()}. */
-@Beta
-public abstract class DaggerContentProvider extends ContentProvider {
-  @CallSuper
-  @Override
-  public boolean onCreate() {
-    AndroidInjection.inject(this);
-    return true;
-  }
-}
diff --git a/java/dagger/android/DaggerDialogFragment.java b/java/dagger/android/DaggerDialogFragment.java
deleted file mode 100644
index 3cbc0f1..0000000
--- a/java/dagger/android/DaggerDialogFragment.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.content.Context;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * A {@link DialogFragment} that injects its members in {@link #onAttach(Context)} and can be used
- * to inject child {@link Fragment}s attached to it. Note that when this fragment gets reattached,
- * its members will be injected again.
- *
- * @deprecated Framework fragments are deprecated in Android P; prefer {@code
- *     dagger.android.support.DaggerDialogFragment} to use a support-library-friendly {@code
- *     dagger.android} dialog fragment implementation.
- */
-@Deprecated
-@Beta
-public abstract class DaggerDialogFragment extends DialogFragment implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onAttach(Context context) {
-    AndroidInjection.inject(this);
-    super.onAttach(context);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/DaggerFragment.java b/java/dagger/android/DaggerFragment.java
deleted file mode 100644
index 187820b..0000000
--- a/java/dagger/android/DaggerFragment.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.Fragment;
-import android.content.Context;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * A {@link Fragment} that injects its members in {@link #onAttach(Context)} and can be used to
- * inject child {@link Fragment}s attached to it. Note that when this fragment gets reattached, its
- * members will be injected again.
- *
- * @deprecated Framework fragments are deprecated in Android P; prefer {@code
- *     dagger.android.support.DaggerFragment} to use a support-library-friendly {@code
- *     dagger.android} fragment implementation.
- */
-@Beta
-@Deprecated
-public abstract class DaggerFragment extends Fragment implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onAttach(Context context) {
-    AndroidInjection.inject(this);
-    super.onAttach(context);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/DaggerIntentService.java b/java/dagger/android/DaggerIntentService.java
deleted file mode 100644
index 7d9dabb..0000000
--- a/java/dagger/android/DaggerIntentService.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import android.app.IntentService;
-import dagger.internal.Beta;
-
-/** An {@link IntentService} that injects its members in {@link #onCreate()}. */
-@Beta
-public abstract class DaggerIntentService extends IntentService {
-  public DaggerIntentService(String name) {
-    super(name);
-  }
-
-  @Override
-  public void onCreate() {
-    AndroidInjection.inject(this);
-    super.onCreate();
-  }
-}
diff --git a/java/dagger/android/DaggerService.java b/java/dagger/android/DaggerService.java
deleted file mode 100644
index cfc6d6b..0000000
--- a/java/dagger/android/DaggerService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import android.app.Service;
-import dagger.internal.Beta;
-
-/** A {@link Service} that injects its members in {@link #onCreate()}. */
-@Beta
-public abstract class DaggerService extends Service {
-  @Override
-  public void onCreate() {
-    AndroidInjection.inject(this);
-    super.onCreate();
-  }
-}
diff --git a/java/dagger/android/DispatchingAndroidInjector.java b/java/dagger/android/DispatchingAndroidInjector.java
deleted file mode 100644
index 9b65180..0000000
--- a/java/dagger/android/DispatchingAndroidInjector.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize;
-import static dagger.internal.Preconditions.checkNotNull;
-
-import android.app.Activity;
-import android.app.Fragment;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import dagger.internal.Beta;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/**
- * Performs members-injection on instances of core Android types (e.g. {@link Activity}, {@link
- * Fragment}) that are constructed by the Android framework and not by Dagger. This class relies on
- * an injected mapping from each concrete class to an {@link AndroidInjector.Factory} for an {@link
- * AndroidInjector} of that class. Each concrete class must have its own entry in the map, even if
- * it extends another class which is already present in the map. Calls {@link Object#getClass()} on
- * the instance in order to find the appropriate {@link AndroidInjector.Factory}.
- *
- * @param <T> the core Android type to be injected
- */
-@Beta
-public final class DispatchingAndroidInjector<T> implements AndroidInjector<T> {
-  private static final String NO_SUPERTYPES_BOUND_FORMAT =
-      "No injector factory bound for Class<%s>";
-  private static final String SUPERTYPES_BOUND_FORMAT =
-      "No injector factory bound for Class<%1$s>. Injector factories were bound for supertypes "
-          + "of %1$s: %2$s. Did you mean to bind an injector factory for the subtype?";
-
-  private final Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactories;
-
-  @Inject
-  DispatchingAndroidInjector(
-      Map<Class<?>, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithClassKeys,
-      Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys) {
-    this.injectorFactories = merge(injectorFactoriesWithClassKeys, injectorFactoriesWithStringKeys);
-  }
-
-  /**
-   * Merges the two maps into one by transforming the values of the {@code classKeyedMap} with
-   * {@link Class#getName()}.
-   *
-   * <p>An SPI plugin verifies the logical uniqueness of the keysets of these two maps so we're
-   * assured there's no overlap.
-   *
-   * <p>Ideally we could achieve this with a generic {@code @Provides} method, but we'd need to have
-   * <i>N</i> modules that each extend one base module.
-   */
-  private static <C, V> Map<String, Provider<AndroidInjector.Factory<?>>> merge(
-      Map<Class<? extends C>, V> classKeyedMap, Map<String, V> stringKeyedMap) {
-    if (classKeyedMap.isEmpty()) {
-      @SuppressWarnings({"unchecked", "rawtypes"})
-      Map<String, Provider<AndroidInjector.Factory<?>>> safeCast = (Map) stringKeyedMap;
-      return safeCast;
-    }
-
-    Map<String, V> merged =
-        newLinkedHashMapWithExpectedSize(classKeyedMap.size() + stringKeyedMap.size());
-    merged.putAll(stringKeyedMap);
-    for (Entry<Class<? extends C>, V> entry : classKeyedMap.entrySet()) {
-      merged.put(entry.getKey().getName(), entry.getValue());
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    Map<String, Provider<AndroidInjector.Factory<?>>> safeCast = (Map) merged;
-    return Collections.unmodifiableMap(safeCast);
-  }
-
-  /**
-   * Attempts to perform members-injection on {@code instance}, returning {@code true} if
-   * successful, {@code false} otherwise.
-   *
-   * @throws InvalidInjectorBindingException if the injector factory bound for a class does not
-   *     inject instances of that class
-   */
-  @CanIgnoreReturnValue
-  public boolean maybeInject(T instance) {
-    Provider<AndroidInjector.Factory<?>> factoryProvider =
-        injectorFactories.get(instance.getClass().getName());
-    if (factoryProvider == null) {
-      return false;
-    }
-
-    @SuppressWarnings("unchecked")
-    AndroidInjector.Factory<T> factory = (AndroidInjector.Factory<T>) factoryProvider.get();
-    try {
-      AndroidInjector<T> injector =
-          checkNotNull(
-              factory.create(instance), "%s.create(I) should not return null.", factory.getClass());
-
-      injector.inject(instance);
-      return true;
-    } catch (ClassCastException e) {
-      throw new InvalidInjectorBindingException(
-          String.format(
-              "%s does not implement AndroidInjector.Factory<%s>",
-              factory.getClass().getCanonicalName(), instance.getClass().getCanonicalName()),
-          e);
-    }
-  }
-
-  /**
-   * Performs members-injection on {@code instance}.
-   *
-   * @throws InvalidInjectorBindingException if the injector factory bound for a class does not
-   *     inject instances of that class
-   * @throws IllegalArgumentException if no {@link AndroidInjector.Factory} is bound for {@code
-   *     instance}
-   */
-  @Override
-  public void inject(T instance) {
-    boolean wasInjected = maybeInject(instance);
-    if (!wasInjected) {
-      throw new IllegalArgumentException(errorMessageSuggestions(instance));
-    }
-  }
-
-  /**
-   * Exception thrown if an incorrect binding is made for a {@link AndroidInjector.Factory}. If you
-   * see this exception, make sure the value in your {@code @ActivityKey(YourActivity.class)} or
-   * {@code @FragmentKey(YourFragment.class)} matches the type argument of the injector factory.
-   */
-  @Beta
-  public static final class InvalidInjectorBindingException extends RuntimeException {
-    InvalidInjectorBindingException(String message, ClassCastException cause) {
-      super(message, cause);
-    }
-  }
-
-  /** Returns an error message with the class names that are supertypes of {@code instance}. */
-  private String errorMessageSuggestions(T instance) {
-    List<String> suggestions = new ArrayList<>();
-    for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
-      if (injectorFactories.containsKey(clazz.getCanonicalName())) {
-        suggestions.add(clazz.getCanonicalName());
-      }
-    }
-
-    return suggestions.isEmpty()
-        ? String.format(NO_SUPERTYPES_BOUND_FORMAT, instance.getClass().getCanonicalName())
-        : String.format(
-            SUPERTYPES_BOUND_FORMAT, instance.getClass().getCanonicalName(), suggestions);
-  }
-}
diff --git a/java/dagger/android/HasActivityInjector.java b/java/dagger/android/HasActivityInjector.java
deleted file mode 100644
index 136bbad..0000000
--- a/java/dagger/android/HasActivityInjector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.Activity;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link Activity}s. */
-@Beta
-public interface HasActivityInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link Activity}s. */
-  AndroidInjector<Activity> activityInjector();
-}
diff --git a/java/dagger/android/HasAndroidInjector.java b/java/dagger/android/HasAndroidInjector.java
deleted file mode 100644
index 3b49718..0000000
--- a/java/dagger/android/HasAndroidInjector.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector}. */
-@Beta
-public interface HasAndroidInjector {
-  /** Returns an {@link AndroidInjector}. */
-  AndroidInjector<Object> androidInjector();
-}
diff --git a/java/dagger/android/HasBroadcastReceiverInjector.java b/java/dagger/android/HasBroadcastReceiverInjector.java
deleted file mode 100644
index b2aa992..0000000
--- a/java/dagger/android/HasBroadcastReceiverInjector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.content.BroadcastReceiver;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link BroadcastReceiver}s. */
-@Beta
-public interface HasBroadcastReceiverInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link BroadcastReceiver}s. */
-  AndroidInjector<BroadcastReceiver> broadcastReceiverInjector();
-}
diff --git a/java/dagger/android/HasContentProviderInjector.java b/java/dagger/android/HasContentProviderInjector.java
deleted file mode 100644
index 997ddb8..0000000
--- a/java/dagger/android/HasContentProviderInjector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.content.ContentProvider;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link ContentProvider}s. */
-@Beta
-public interface HasContentProviderInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link ContentProvider}s. */
-  AndroidInjector<ContentProvider> contentProviderInjector();
-}
diff --git a/java/dagger/android/HasFragmentInjector.java b/java/dagger/android/HasFragmentInjector.java
deleted file mode 100644
index 564f32d..0000000
--- a/java/dagger/android/HasFragmentInjector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.Fragment;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link Fragment}s. */
-@Beta
-public interface HasFragmentInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link Fragment}s. */
-  AndroidInjector<Fragment> fragmentInjector();
-}
diff --git a/java/dagger/android/HasServiceInjector.java b/java/dagger/android/HasServiceInjector.java
deleted file mode 100644
index d1c6a6c..0000000
--- a/java/dagger/android/HasServiceInjector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import android.app.Service;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link Service}s. */
-@Beta
-public interface HasServiceInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link Service}s. */
-  AndroidInjector<Service> serviceInjector();
-}
diff --git a/java/dagger/android/internal/AndroidInjectionKeys.java b/java/dagger/android/internal/AndroidInjectionKeys.java
deleted file mode 100644
index f30b92c..0000000
--- a/java/dagger/android/internal/AndroidInjectionKeys.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.internal;
-
-/**
- * An internal implementation detail of Dagger's generated code. This is not guaranteed to remain
- * consistent from version to version.
- */
-public final class AndroidInjectionKeys {
-  /**
-   * Accepts the fully qualified name of a class that is injected with {@code dagger.android}.
-   *
-   * <p>From a runtime perspective, this method does nothing except return its single argument. It
-   * is used as a signal to bytecode shrinking tools that its argument should be rewritten if it
-   * corresponds to a class that has been obfuscated/relocated. Once it is done so, it is expected
-   * that the argument will be inlined and this method will go away.
-   */
-  public static String of(String mapKey) {
-    return mapKey;
-  }
-
-  private AndroidInjectionKeys() {}
-}
diff --git a/java/dagger/android/package-info.java b/java/dagger/android/package-info.java
deleted file mode 100644
index f59ef48..0000000
--- a/java/dagger/android/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-/** APIs to assist with performing injection on Android. */
-@CheckReturnValue
-package dagger.android;
-
-import com.google.errorprone.annotations.CheckReturnValue;
diff --git a/java/dagger/android/processor/AndroidInjectorDescriptor.java b/java/dagger/android/processor/AndroidInjectorDescriptor.java
deleted file mode 100644
index 3ec6613..0000000
--- a/java/dagger/android/processor/AndroidInjectorDescriptor.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
-import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
-import static com.google.auto.common.MoreElements.getAnnotationMirror;
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static java.util.stream.Collectors.toList;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeName;
-import dagger.Module;
-import dagger.android.ContributesAndroidInjector;
-import java.util.List;
-import java.util.Optional;
-import javax.annotation.processing.Messager;
-import javax.inject.Qualifier;
-import javax.inject.Scope;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-import javax.tools.Diagnostic.Kind;
-
-/**
- * A descriptor of a generated {@link Module} and {@link dagger.Subcomponent} to be generated from a
- * {@link ContributesAndroidInjector} method.
- */
-@AutoValue
-abstract class AndroidInjectorDescriptor {
-  /** The type to be injected; the return type of the {@link ContributesAndroidInjector} method. */
-  abstract ClassName injectedType();
-
-  /** Scopes to apply to the generated {@link dagger.Subcomponent}. */
-  abstract ImmutableSet<AnnotationSpec> scopes();
-
-  /** @see ContributesAndroidInjector#modules() */
-  abstract ImmutableSet<ClassName> modules();
-
-  /** The {@link Module} that contains the {@link ContributesAndroidInjector} method. */
-  abstract ClassName enclosingModule();
-
-  /** The method annotated with {@link ContributesAndroidInjector}. */
-  abstract ExecutableElement method();
-
-  @AutoValue.Builder
-  abstract static class Builder {
-    abstract Builder injectedType(ClassName injectedType);
-
-    abstract ImmutableSet.Builder<AnnotationSpec> scopesBuilder();
-
-    abstract ImmutableSet.Builder<ClassName> modulesBuilder();
-
-    abstract Builder enclosingModule(ClassName enclosingModule);
-
-    abstract Builder method(ExecutableElement method);
-
-    abstract AndroidInjectorDescriptor build();
-  }
-
-  static final class Validator {
-    private final Messager messager;
-
-    Validator(Messager messager) {
-      this.messager = messager;
-    }
-
-    /**
-     * Validates a {@link ContributesAndroidInjector} method, returning an {@link
-     * AndroidInjectorDescriptor} if it is valid, or {@link Optional#empty()} otherwise.
-     */
-    Optional<AndroidInjectorDescriptor> createIfValid(ExecutableElement method) {
-      ErrorReporter reporter = new ErrorReporter(method, messager);
-
-      if (!method.getModifiers().contains(ABSTRACT)) {
-        reporter.reportError("@ContributesAndroidInjector methods must be abstract");
-      }
-
-      if (!method.getParameters().isEmpty()) {
-        reporter.reportError("@ContributesAndroidInjector methods cannot have parameters");
-      }
-
-      AndroidInjectorDescriptor.Builder builder =
-          new AutoValue_AndroidInjectorDescriptor.Builder().method(method);
-      TypeElement enclosingElement = MoreElements.asType(method.getEnclosingElement());
-      if (!isAnnotationPresent(enclosingElement, Module.class)) {
-        reporter.reportError("@ContributesAndroidInjector methods must be in a @Module");
-      }
-      builder.enclosingModule(ClassName.get(enclosingElement));
-
-      TypeMirror injectedType = method.getReturnType();
-      if (MoreTypes.asDeclared(injectedType).getTypeArguments().isEmpty()) {
-        builder.injectedType(ClassName.get(MoreTypes.asTypeElement(injectedType)));
-      } else {
-        reporter.reportError(
-            "@ContributesAndroidInjector methods cannot return parameterized types");
-      }
-
-      AnnotationMirror annotation =
-          getAnnotationMirror(method, ContributesAndroidInjector.class).get();
-      for (TypeMirror module :
-          getAnnotationValue(annotation, "modules").accept(new AllTypesVisitor(), null)) {
-        if (isAnnotationPresent(MoreTypes.asElement(module), Module.class)) {
-          builder.modulesBuilder().add((ClassName) TypeName.get(module));
-        } else {
-          reporter.reportError(String.format("%s is not a @Module", module), annotation);
-        }
-      }
-
-      for (AnnotationMirror scope : getAnnotatedAnnotations(method, Scope.class)) {
-        builder.scopesBuilder().add(AnnotationSpec.get(scope));
-      }
-
-      for (AnnotationMirror qualifier : getAnnotatedAnnotations(method, Qualifier.class)) {
-        reporter.reportError(
-            "@ContributesAndroidInjector methods cannot have qualifiers", qualifier);
-      }
-
-      return reporter.hasError ? Optional.empty() : Optional.of(builder.build());
-    }
-
-    // TODO(ronshapiro): use ValidationReport once it is moved out of the compiler
-    private static class ErrorReporter {
-      private final Element subject;
-      private final Messager messager;
-      private boolean hasError;
-
-      ErrorReporter(Element subject, Messager messager) {
-        this.subject = subject;
-        this.messager = messager;
-      }
-
-      void reportError(String error) {
-        hasError = true;
-        messager.printMessage(Kind.ERROR, error, subject);
-      }
-
-      void reportError(String error, AnnotationMirror annotation) {
-        hasError = true;
-        messager.printMessage(Kind.ERROR, error, subject, annotation);
-      }
-    }
-  }
-
-  private static final class AllTypesVisitor
-      extends SimpleAnnotationValueVisitor8<ImmutableSet<TypeMirror>, Void> {
-    @Override
-    public ImmutableSet<TypeMirror> visitArray(List<? extends AnnotationValue> values, Void aVoid) {
-      return ImmutableSet.copyOf(
-          values.stream().flatMap(v -> v.accept(this, null).stream()).collect(toList()));
-    }
-
-    @Override
-    public ImmutableSet<TypeMirror> visitType(TypeMirror a, Void aVoid) {
-      return ImmutableSet.of(a);
-    }
-
-    @Override
-    protected ImmutableSet<TypeMirror> defaultAction(Object o, Void aVoid) {
-      throw new AssertionError(o);
-    }
-  }
-}
diff --git a/java/dagger/android/processor/AndroidMapKeyValidator.java b/java/dagger/android/processor/AndroidMapKeyValidator.java
deleted file mode 100644
index f6e808a..0000000
--- a/java/dagger/android/processor/AndroidMapKeyValidator.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
-import static com.google.auto.common.MoreElements.getAnnotationMirror;
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.android.processor.AndroidMapKeys.injectedTypeFromMapKey;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.SetMultimap;
-import dagger.Binds;
-import dagger.MapKey;
-import dagger.android.AndroidInjectionKey;
-import dagger.android.AndroidInjector;
-import dagger.multibindings.ClassKey;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Qualifier;
-import javax.inject.Scope;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-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;
-
-/** Validates the correctness of {@link MapKey}s used with {@code dagger.android}. */
-final class AndroidMapKeyValidator implements ProcessingStep {
-  private final Elements elements;
-  private final Types types;
-  private final Messager messager;
-
-  AndroidMapKeyValidator(Elements elements, Types types, Messager messager) {
-    this.elements = elements;
-    this.types = types;
-    this.messager = messager;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.<Class<? extends Annotation>>builder()
-        .add(AndroidInjectionKey.class)
-        .add(ClassKey.class)
-        .build();
-  }
-
-  @Override
-  public Set<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder();
-    elementsByAnnotation
-        .entries()
-        .forEach(
-            entry -> {
-              try {
-                validateMethod(entry.getKey(), MoreElements.asExecutable(entry.getValue()));
-              } catch (TypeNotPresentException e) {
-                deferredElements.add(entry.getValue());
-              }
-            });
-    return deferredElements.build();
-  }
-
-  private void validateMethod(Class<? extends Annotation> annotation, ExecutableElement method) {
-    if (!getAnnotatedAnnotations(method, Qualifier.class).isEmpty()) {
-      return;
-    }
-
-    TypeMirror returnType = method.getReturnType();
-    if (!types.isAssignable(types.erasure(returnType), factoryElement().asType())) {
-      // if returnType is not related to AndroidInjector.Factory, ignore the method
-      return;
-    }
-
-    if (!getAnnotatedAnnotations(method, Scope.class).isEmpty()) {
-      SuppressWarnings suppressedWarnings = method.getAnnotation(SuppressWarnings.class);
-      if (suppressedWarnings == null
-          || !ImmutableSet.copyOf(suppressedWarnings.value())
-              .contains("dagger.android.ScopedInjectorFactory")) {
-        AnnotationMirror mapKeyAnnotation =
-            getOnlyElement(getAnnotatedAnnotations(method, MapKey.class));
-        TypeElement mapKeyValueElement =
-            elements.getTypeElement(injectedTypeFromMapKey(mapKeyAnnotation).get());
-        messager.printMessage(
-            Kind.ERROR,
-            String.format(
-                "%s bindings should not be scoped. Scoping this method may leak instances of %s.",
-                AndroidInjector.Factory.class.getCanonicalName(),
-                mapKeyValueElement.getQualifiedName()),
-            method);
-      }
-    }
-
-    validateReturnType(method);
-
-    // @Binds methods should only have one parameter, but we can't guarantee the order of Processors
-    // in javac, so do a basic check for valid form
-    if (isAnnotationPresent(method, Binds.class) && method.getParameters().size() == 1) {
-      validateMapKeyMatchesBindsParameter(annotation, method);
-    }
-  }
-
-  /** Report an error if the method's return type is not {@code AndroidInjector.Factory<?>}. */
-  private void validateReturnType(ExecutableElement method) {
-    TypeMirror returnType = method.getReturnType();
-    DeclaredType requiredReturnType = injectorFactoryOf(types.getWildcardType(null, null));
-
-    if (!types.isSameType(returnType, requiredReturnType)) {
-      messager.printMessage(
-          Kind.ERROR,
-          String.format(
-              "%s should bind %s, not %s. See https://dagger.dev/android",
-              method, requiredReturnType, returnType),
-          method);
-    }
-  }
-
-  /**
-   * A valid @Binds method could bind an {@link AndroidInjector.Factory} for one type, while giving
-   * it a map key of a different type. The return type and parameter type would pass typical @Binds
-   * validation, but the map lookup in {@link dagger.android.DispatchingAndroidInjector} would
-   * retrieve the wrong injector factory.
-   *
-   * <pre>{@code
-   * {@literal @Binds}
-   * {@literal @IntoMap}
-   * {@literal @ClassKey(GreenActivity.class)}
-   * abstract AndroidInjector.Factory<?> bindBlueActivity(
-   *     BlueActivityComponent.Builder builder);
-   * }</pre>
-   */
-  private void validateMapKeyMatchesBindsParameter(
-      Class<? extends Annotation> annotation, ExecutableElement method) {
-    TypeMirror parameterType = getOnlyElement(method.getParameters()).asType();
-    AnnotationMirror annotationMirror = getAnnotationMirror(method, annotation).get();
-    TypeMirror mapKeyType =
-        elements.getTypeElement(injectedTypeFromMapKey(annotationMirror).get()).asType();
-    if (!types.isAssignable(parameterType, injectorFactoryOf(mapKeyType))) {
-      messager.printMessage(
-          Kind.ERROR,
-          String.format("%s does not implement AndroidInjector<%s>", parameterType, mapKeyType),
-          method,
-          annotationMirror);
-    }
-  }
-
-  /** Returns a {@link DeclaredType} for {@code AndroidInjector.Factory<implementationType>}. */
-  private DeclaredType injectorFactoryOf(TypeMirror implementationType) {
-    return types.getDeclaredType(factoryElement(), implementationType);
-  }
-
-  private TypeElement factoryElement() {
-    return elements.getTypeElement(AndroidInjector.Factory.class.getCanonicalName());
-  }
-}
diff --git a/java/dagger/android/processor/AndroidMapKeys.java b/java/dagger/android/processor/AndroidMapKeys.java
deleted file mode 100644
index fb1fc38..0000000
--- a/java/dagger/android/processor/AndroidMapKeys.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
-
-import com.google.auto.common.MoreTypes;
-import dagger.android.AndroidInjectionKey;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-final class AndroidMapKeys {
-  /**
-   * If {@code mapKey} is {@link AndroidInjectionKey}, returns the string value for the map key. If
-   * it's {@link dagger.multibindings.ClassKey}, returns the fully-qualified class name of the
-   * annotation value. Otherwise returns {@link Optional#empty()}.
-   */
-  static Optional<String> injectedTypeFromMapKey(AnnotationMirror mapKey) {
-    Object mapKeyClass = getAnnotationValue(mapKey, "value").getValue();
-    if (mapKeyClass instanceof String) {
-      return Optional.of((String) mapKeyClass);
-    } else if (mapKeyClass instanceof TypeMirror) {
-      TypeElement type = MoreTypes.asTypeElement((TypeMirror) mapKeyClass);
-      return Optional.of(type.getQualifiedName().toString());
-    } else {
-      return Optional.empty();
-    }
-  }
-}
diff --git a/java/dagger/android/processor/AndroidProcessor.java b/java/dagger/android/processor/AndroidProcessor.java
deleted file mode 100644
index 5c17341..0000000
--- a/java/dagger/android/processor/AndroidProcessor.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static javax.tools.Diagnostic.Kind.ERROR;
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-import static net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING;
-
-import com.google.auto.common.BasicAnnotationProcessor;
-import com.google.auto.service.AutoService;
-import com.google.common.base.Ascii;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.googlejavaformat.java.filer.FormattingFiler;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.Processor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
-
-/**
- * An {@linkplain javax.annotation.processing.Processor annotation processor} to verify usage of
- * {@code dagger.android} code.
- *
- * <p>Additionally, if {@code -Adagger.android.experimentalUseStringKeys} is passed to the
- * compilation, a file will be generated to support obfuscated injected Android types used with
- * {@code @AndroidInjectionKey}. The fact that this is generated is deliberate: not all versions of
- * ProGuard/R8 support {@code -identifiernamestring}, so we can't include a ProGuard file in the
- * dagger-android artifact Instead, we generate the file in {@code META-INF/proguard} only when
- * users enable the flag. They should only be enabling it if their shrinker supports those files,
- * and any version that does so will also support {@code -identifiernamestring}. This was added to
- * R8 in <a href="https://r8.googlesource.com/r8/+/389123dfcc11e6dda0eec31ab62e1b7eb0da80d2">May
- * 2018</a>.
- */
-@IncrementalAnnotationProcessor(ISOLATING)
-@AutoService(Processor.class)
-public final class AndroidProcessor extends BasicAnnotationProcessor {
-  private static final String FLAG_EXPERIMENTAL_USE_STRING_KEYS =
-      "dagger.android.experimentalUseStringKeys";
-
-  @Override
-  protected Iterable<? extends ProcessingStep> initSteps() {
-    Filer filer = new FormattingFiler(processingEnv.getFiler());
-    Messager messager = processingEnv.getMessager();
-    Elements elements = processingEnv.getElementUtils();
-    Types types = processingEnv.getTypeUtils();
-
-    return ImmutableList.of(
-        new AndroidMapKeyValidator(elements, types, messager),
-        new ContributesAndroidInjectorGenerator(
-            new AndroidInjectorDescriptor.Validator(messager),
-            useStringKeys(),
-            filer,
-            elements,
-            processingEnv.getSourceVersion()));
-  }
-
-  private boolean useStringKeys() {
-    if (!processingEnv.getOptions().containsKey(FLAG_EXPERIMENTAL_USE_STRING_KEYS)) {
-      return false;
-    }
-    String flagValue = processingEnv.getOptions().get(FLAG_EXPERIMENTAL_USE_STRING_KEYS);
-    if (flagValue == null || Ascii.equalsIgnoreCase(flagValue, "true")) {
-      return true;
-    } else if (Ascii.equalsIgnoreCase(flagValue, "false")) {
-      return false;
-    } else {
-      processingEnv
-          .getMessager()
-          .printMessage(
-              ERROR,
-              String.format(
-                  "Unknown flag value: %s. %s must be set to either 'true' or 'false'.",
-                  flagValue, FLAG_EXPERIMENTAL_USE_STRING_KEYS));
-      return false;
-    }
-  }
-
-  @Override
-  protected void postRound(RoundEnvironment roundEnv) {
-    if (roundEnv.processingOver() && useStringKeys()) {
-      try (Writer writer = createProguardFile()){
-        writer.write(
-            Joiner.on("\n")
-                .join(
-                    "-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {",
-                    "  java.lang.String of(java.lang.String);",
-                    "}"));
-      } catch (IOException e) {
-        e.printStackTrace();
-      }
-    }
-  }
-
-  private Writer createProguardFile() throws IOException {
-    return processingEnv
-        .getFiler()
-        .createResource(CLASS_OUTPUT, "", "META-INF/proguard/dagger.android.AndroidInjectionKeys")
-        .openWriter();
-  }
-
-  @Override
-  public Set<String> getSupportedOptions() {
-    return ImmutableSet.of(FLAG_EXPERIMENTAL_USE_STRING_KEYS);
-  }
-
-  @Override
-  public SourceVersion getSupportedSourceVersion() {
-    return SourceVersion.latestSupported();
-  }
-}
diff --git a/java/dagger/android/processor/BUILD b/java/dagger/android/processor/BUILD
deleted file mode 100644
index 5754143..0000000
--- a/java/dagger/android/processor/BUILD
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Public Dagger API for Android
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-load("//tools:maven.bzl", "POM_VERSION", "pom_file")
-
-filegroup(
-    name = "srcs",
-    srcs = glob(["*.java"]),
-)
-
-java_library(
-    name = "processor",
-    srcs = [":srcs"],
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    tags = ["maven_coordinates=com.google.dagger:dagger-android-processor:" + POM_VERSION],
-    deps = [
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/incap",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/google_java_format",
-        "//java/dagger:core",
-        "//java/dagger/model",
-        "//java/dagger/spi",
-        # https://github.com/bazelbuild/bazel/issues/2517
-        ":dagger-android-jar",
-    ],
-)
-
-# https://github.com/bazelbuild/bazel/issues/2517
-# This target serves two (related) purposes:
-# 1. Bazel does not allow a java_library to depend on an android_library, even if that java_library
-# will be used in a java_plugin.
-# 2. It stores the metadata for the "jarimpl" target that we use to work-around Gradle not loading
-# aar artifacts that are declared as deps of an annotation processor. Our pom.xml generator reads
-# the tags and includes them apppropriately.
-java_import(
-    name = "dagger-android-jar",
-    jars = ["//java/dagger/android:libandroid.jar"],
-    tags = ["maven_coordinates=com.google.dagger:dagger-android-jarimpl:" + POM_VERSION],
-    visibility = ["//visibility:private"],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-android-processor",
-    artifact_name = "Dagger Android Processor",
-    targets = [":processor"],
-)
-
-java_plugin(
-    name = "plugin",
-    generates_api = 1,
-    processor_class = "dagger.android.processor.AndroidProcessor",
-    deps = [":processor"],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "processor-javadoc",
-    srcs = [":srcs"],
-    root_packages = ["dagger.android.processor"],
-    deps = [":processor"],
-)
diff --git a/java/dagger/android/processor/ContributesAndroidInjectorGenerator.java b/java/dagger/android/processor/ContributesAndroidInjectorGenerator.java
deleted file mode 100644
index 5c99fd4..0000000
--- a/java/dagger/android/processor/ContributesAndroidInjectorGenerator.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;
-import static com.google.common.base.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static com.squareup.javapoet.TypeSpec.interfaceBuilder;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.SetMultimap;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.WildcardTypeName;
-import dagger.Binds;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.android.AndroidInjectionKey;
-import dagger.android.AndroidInjector;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.processor.AndroidInjectorDescriptor.Validator;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.util.Elements;
-
-/** Generates the implementation specified in {@link ContributesAndroidInjector}. */
-final class ContributesAndroidInjectorGenerator implements ProcessingStep {
-
-  private final AndroidInjectorDescriptor.Validator validator;
-  private final Filer filer;
-  private final Elements elements;
-  private final boolean useStringKeys;
-  private final SourceVersion sourceVersion;
-
-  ContributesAndroidInjectorGenerator(
-      Validator validator,
-      boolean useStringKeys,
-      Filer filer,
-      Elements elements,
-      SourceVersion sourceVersion) {
-    this.validator = validator;
-    this.useStringKeys = useStringKeys;
-    this.filer = filer;
-    this.elements = elements;
-    this.sourceVersion = sourceVersion;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(ContributesAndroidInjector.class);
-  }
-
-  @Override
-  public Set<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder();
-    for (ExecutableElement method : methodsIn(elementsByAnnotation.values())) {
-      try {
-        validator.createIfValid(method).ifPresent(this::generate);
-      } catch (TypeNotPresentException e) {
-        deferredElements.add(method);
-      }
-    }
-    return deferredElements.build();
-  }
-
-  private void generate(AndroidInjectorDescriptor descriptor) {
-    ClassName moduleName =
-        descriptor
-            .enclosingModule()
-            .topLevelClassName()
-            .peerClass(
-                Joiner.on('_').join(descriptor.enclosingModule().simpleNames())
-                    + "_"
-                    + LOWER_CAMEL.to(UPPER_CAMEL, descriptor.method().getSimpleName().toString()));
-
-    String baseName = descriptor.injectedType().simpleName();
-    ClassName subcomponentName = moduleName.nestedClass(baseName + "Subcomponent");
-    ClassName subcomponentFactoryName = subcomponentName.nestedClass("Factory");
-
-    TypeSpec.Builder module =
-        classBuilder(moduleName)
-            .addOriginatingElement(descriptor.method())
-            .addAnnotation(
-                AnnotationSpec.builder(Module.class)
-                    .addMember("subcomponents", "$T.class", subcomponentName)
-                    .build())
-            .addModifiers(PUBLIC, ABSTRACT)
-            .addMethod(bindAndroidInjectorFactory(descriptor, subcomponentFactoryName))
-            .addType(subcomponent(descriptor, subcomponentName, subcomponentFactoryName))
-            .addMethod(constructorBuilder().addModifiers(PRIVATE).build());
-    generatedAnnotationSpec(elements, sourceVersion, AndroidProcessor.class)
-        .ifPresent(module::addAnnotation);
-
-    try {
-      JavaFile.builder(moduleName.packageName(), module.build())
-          .skipJavaLangImports(true)
-          .build()
-          .writeTo(filer);
-    } catch (IOException e) {
-      throw new AssertionError(e);
-    }
-  }
-
-  private MethodSpec bindAndroidInjectorFactory(
-      AndroidInjectorDescriptor descriptor, ClassName subcomponentBuilderName) {
-    return methodBuilder("bindAndroidInjectorFactory")
-        .addAnnotation(Binds.class)
-        .addAnnotation(IntoMap.class)
-        .addAnnotation(androidInjectorMapKey(descriptor))
-        .addModifiers(ABSTRACT)
-        .returns(
-            parameterizedTypeName(
-                AndroidInjector.Factory.class,
-                WildcardTypeName.subtypeOf(TypeName.OBJECT)))
-        .addParameter(subcomponentBuilderName, "builder")
-        .build();
-  }
-
-  private AnnotationSpec androidInjectorMapKey(AndroidInjectorDescriptor descriptor) {
-    if (useStringKeys) {
-      return AnnotationSpec.builder(AndroidInjectionKey.class)
-          .addMember("value", "$S", descriptor.injectedType().toString())
-          .build();
-    }
-    return AnnotationSpec.builder(ClassKey.class)
-        .addMember("value", "$T.class", descriptor.injectedType())
-        .build();
-  }
-
-  private TypeSpec subcomponent(
-      AndroidInjectorDescriptor descriptor,
-      ClassName subcomponentName,
-      ClassName subcomponentFactoryName) {
-    AnnotationSpec.Builder subcomponentAnnotation = AnnotationSpec.builder(Subcomponent.class);
-    for (ClassName module : descriptor.modules()) {
-      subcomponentAnnotation.addMember("modules", "$T.class", module);
-    }
-
-    return interfaceBuilder(subcomponentName)
-        .addModifiers(PUBLIC)
-        .addAnnotation(subcomponentAnnotation.build())
-        .addAnnotations(descriptor.scopes())
-        .addSuperinterface(parameterizedTypeName(AndroidInjector.class, descriptor.injectedType()))
-        .addType(subcomponentFactory(descriptor, subcomponentFactoryName))
-        .build();
-  }
-
-  private TypeSpec subcomponentFactory(
-      AndroidInjectorDescriptor descriptor, ClassName subcomponentFactoryName) {
-    return interfaceBuilder(subcomponentFactoryName)
-        .addAnnotation(Subcomponent.Factory.class)
-        .addModifiers(PUBLIC, STATIC)
-        .addSuperinterface(
-            parameterizedTypeName(AndroidInjector.Factory.class, descriptor.injectedType()))
-        .build();
-  }
-
-  private static ParameterizedTypeName parameterizedTypeName(
-      Class<?> clazz, TypeName... typeArguments) {
-    return ParameterizedTypeName.get(ClassName.get(clazz), typeArguments);
-  }
-}
diff --git a/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java b/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java
deleted file mode 100644
index a19c5ef..0000000
--- a/java/dagger/android/processor/DuplicateAndroidInjectorsChecker.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.processor;
-
-import static com.google.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.android.processor.AndroidMapKeys.injectedTypeFromMapKey;
-import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.toList;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.service.AutoService;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimaps;
-import dagger.MapKey;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.model.Binding;
-import dagger.model.BindingGraph;
-import dagger.model.BindingKind;
-import dagger.model.Key;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.Formatter;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Stream;
-import javax.inject.Provider;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Validates that the two maps that {@link DispatchingAndroidInjector} injects have logically
- * different keys. If a contribution exists for the same {@code FooActivity} with
- * {@code @ActivityKey(FooActivity.class)} and
- * {@code @AndroidInjectionKey("com.example.FooActivity")}, report an error.
- */
-@AutoService(BindingGraphPlugin.class)
-public final class DuplicateAndroidInjectorsChecker implements BindingGraphPlugin {
-  @Override
-  public void visitGraph(BindingGraph graph, DiagnosticReporter diagnosticReporter) {
-    for (Binding binding : graph.bindings()) {
-      if (isDispatchingAndroidInjector(binding)) {
-        validateMapKeyUniqueness(binding, graph, diagnosticReporter);
-      }
-    }
-  }
-
-  private boolean isDispatchingAndroidInjector(Binding binding) {
-    Key key = binding.key();
-    return MoreTypes.isTypeOf(DispatchingAndroidInjector.class, key.type())
-        && !key.qualifier().isPresent();
-  }
-
-  private void validateMapKeyUniqueness(
-      Binding dispatchingAndroidInjector,
-      BindingGraph graph,
-      DiagnosticReporter diagnosticReporter) {
-    ImmutableSet<Binding> injectorFactories =
-        injectorMapDependencies(dispatchingAndroidInjector, graph)
-            .flatMap(injectorFactoryMap -> graph.requestedBindings(injectorFactoryMap).stream())
-            .collect(collectingAndThen(toList(), ImmutableSet::copyOf));
-
-    ImmutableListMultimap.Builder<String, Binding> mapKeyIndex = ImmutableListMultimap.builder();
-    for (Binding injectorFactory : injectorFactories) {
-      AnnotationMirror mapKey = mapKey(injectorFactory).get();
-      Optional<String> injectedType = injectedTypeFromMapKey(mapKey);
-      if (injectedType.isPresent()) {
-        mapKeyIndex.put(injectedType.get(), injectorFactory);
-      } else {
-        diagnosticReporter.reportBinding(
-            ERROR, injectorFactory, "Unrecognized class: %s", mapKey);
-      }
-    }
-
-    Map<String, List<Binding>> duplicates =
-        Maps.filterValues(Multimaps.asMap(mapKeyIndex.build()), bindings -> bindings.size() > 1);
-    if (!duplicates.isEmpty()) {
-      StringBuilder errorMessage =
-          new StringBuilder("Multiple injector factories bound for the same type:\n");
-      Formatter formatter = new Formatter(errorMessage);
-      duplicates.forEach(
-          (injectedType, duplicateFactories) -> {
-            formatter.format("  %s:\n", injectedType);
-            duplicateFactories.forEach(duplicate -> formatter.format("    %s\n", duplicate));
-          });
-      diagnosticReporter.reportBinding(ERROR, dispatchingAndroidInjector, errorMessage.toString());
-    }
-  }
-
-  /**
-   * Returns a stream of the dependencies of {@code binding} that have a key type of {@code Map<K,
-   * Provider<AndroidInjector.Factory<?>>}.
-   */
-  private Stream<Binding> injectorMapDependencies(Binding binding, BindingGraph graph) {
-    return graph.requestedBindings(binding).stream()
-        .filter(requestedBinding -> requestedBinding.kind().equals(BindingKind.MULTIBOUND_MAP))
-        .filter(
-            requestedBinding -> {
-              TypeMirror valueType =
-                  MoreTypes.asDeclared(requestedBinding.key().type()).getTypeArguments().get(1);
-              if (!MoreTypes.isTypeOf(Provider.class, valueType)
-                  || !valueType.getKind().equals(TypeKind.DECLARED)) {
-                return false;
-              }
-              TypeMirror providedType = MoreTypes.asDeclared(valueType).getTypeArguments().get(0);
-              return MoreTypes.isTypeOf(AndroidInjector.Factory.class, providedType);
-            });
-  }
-
-  private Optional<AnnotationMirror> mapKey(Binding binding) {
-    return binding
-        .bindingElement()
-        .map(bindingElement -> getAnnotatedAnnotations(bindingElement, MapKey.class))
-        .flatMap(
-            annotations ->
-                annotations.isEmpty()
-                    ? Optional.empty()
-                    : Optional.of(getOnlyElement(annotations)));
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/Android/DuplicateAndroidInjectors";
-  }
-}
diff --git a/java/dagger/android/proguard.cfg b/java/dagger/android/proguard.cfg
deleted file mode 100644
index bd8ffbf..0000000
--- a/java/dagger/android/proguard.cfg
+++ /dev/null
@@ -1 +0,0 @@
--dontwarn com.google.errorprone.annotations.**
diff --git a/java/dagger/android/support/AndroidManifest.xml b/java/dagger/android/support/AndroidManifest.xml
deleted file mode 100644
index d080e11..0000000
--- a/java/dagger/android/support/AndroidManifest.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="dagger.android.support">
-  <uses-sdk android:minSdkVersion="14" />
-</manifest>
diff --git a/java/dagger/android/support/AndroidSupportInjection.java b/java/dagger/android/support/AndroidSupportInjection.java
deleted file mode 100644
index 1624345..0000000
--- a/java/dagger/android/support/AndroidSupportInjection.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import static android.util.Log.DEBUG;
-import static dagger.internal.Preconditions.checkNotNull;
-
-import android.app.Activity;
-import android.app.Application;
-import android.support.v4.app.Fragment;
-import android.util.Log;
-import dagger.android.AndroidInjector;
-import dagger.android.HasAndroidInjector;
-import dagger.internal.Beta;
-
-/** Injects core Android types from support libraries. */
-@Beta
-public final class AndroidSupportInjection {
-  private static final String TAG = "dagger.android.support";
-
-  /**
-   * Injects {@code fragment} if an associated {@link AndroidInjector} implementation can be found,
-   * otherwise throws an {@link IllegalArgumentException}.
-   *
-   * <p>Uses the following algorithm to find the appropriate {@link AndroidInjector} to use to
-   * inject {@code fragment}:
-   *
-   * <ol>
-   *   <li>Walks the parent-fragment hierarchy to find a fragment that implements {@link
-   *       HasAndroidInjector} or {@link HasSupportFragmentInjector}, and if none do
-   *   <li>Uses the {@code fragment}'s {@link Fragment#getActivity() activity} if it implements
-   *       {@link HasAndroidInjector} or {@link HasSupportFragmentInjector}, and if not
-   *   <li>Uses the {@link android.app.Application} if it implements {@link HasAndroidInjector}
-   *       {@link HasSupportFragmentInjector}.
-   * </ol>
-   *
-   * If none of them implement {@link HasAndroidInjector} or {@link HasSupportFragmentInjector}, a
-   * {@link IllegalArgumentException} is thrown.
-   *
-   * @throws IllegalArgumentException if no parent fragment, activity, or application implements
-   *     {@link HasAndroidInjector} or {@link HasSupportFragmentInjector}.
-   */
-  public static void inject(Fragment fragment) {
-    checkNotNull(fragment, "fragment");
-
-    Object hasInjector = findHasSupportFragmentInjector(fragment);
-    AndroidInjector<? super Fragment> injector;
-    if (hasInjector instanceof HasAndroidInjector) {
-      injector = ((HasAndroidInjector) hasInjector).androidInjector();
-      checkNotNull(injector, "%s.androidInjector() returned null", hasInjector.getClass());
-    } else if (hasInjector instanceof HasSupportFragmentInjector) {
-      injector = ((HasSupportFragmentInjector) hasInjector).supportFragmentInjector();
-      checkNotNull(injector, "%s.supportFragmentInjector() returned null", hasInjector.getClass());
-    } else {
-      throw new RuntimeException(
-          String.format(
-              "%s does not implement %s or %s",
-              hasInjector.getClass().getCanonicalName(),
-              HasAndroidInjector.class.getCanonicalName(),
-              HasSupportFragmentInjector.class.getCanonicalName()));
-    }
-
-    if (Log.isLoggable(TAG, DEBUG)) {
-      Log.d(
-          TAG,
-          String.format(
-              "An injector for %s was found in %s",
-              fragment.getClass().getCanonicalName(),
-              hasInjector.getClass().getCanonicalName()));
-    }
-
-    injector.inject(fragment);
-  }
-
-  private static Object findHasSupportFragmentInjector(Fragment fragment) {
-    Fragment parentFragment = fragment;
-    while ((parentFragment = parentFragment.getParentFragment()) != null) {
-      if (parentFragment instanceof HasAndroidInjector
-          || parentFragment instanceof HasSupportFragmentInjector) {
-        return parentFragment;
-      }
-    }
-    Activity activity = fragment.getActivity();
-    if (activity instanceof HasAndroidInjector || activity instanceof HasSupportFragmentInjector) {
-      return activity;
-    }
-    Application application = activity.getApplication();
-    if (application instanceof HasAndroidInjector
-        || application instanceof HasSupportFragmentInjector) {
-      return application;
-    }
-    throw new IllegalArgumentException(
-        String.format("No injector was found for %s", fragment.getClass().getCanonicalName()));
-  }
-
-  private AndroidSupportInjection() {}
-}
diff --git a/java/dagger/android/support/AndroidSupportInjectionModule.java b/java/dagger/android/support/AndroidSupportInjectionModule.java
deleted file mode 100644
index d78b0cb..0000000
--- a/java/dagger/android/support/AndroidSupportInjectionModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import dagger.Module;
-import dagger.android.AndroidInjectionModule;
-import dagger.internal.Beta;
-
-/**
- * This module no longer provides any value beyond what is provided in {@link
- * AndroidInjectionModule} and is just an alias. It will be removed in a future release.
- */
-@Beta
-@Module(includes = AndroidInjectionModule.class)
-public abstract class AndroidSupportInjectionModule {
-  private AndroidSupportInjectionModule() {}
-}
diff --git a/java/dagger/android/support/BUILD b/java/dagger/android/support/BUILD
deleted file mode 100644
index 749d541..0000000
--- a/java/dagger/android/support/BUILD
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   Public Dagger API for Android that interacts with the Android support libraries
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "SOURCE_7_TARGET_7")
-load("//tools:maven.bzl", "pom_file", "POM_VERSION")
-
-filegroup(
-    name = "support-srcs",
-    srcs = glob(["*.java"]),
-)
-
-android_library(
-    name = "support",
-    srcs = glob(["*.java"]),
-    javacopts = SOURCE_7_TARGET_7,
-    manifest = "AndroidManifest.xml",
-    tags = ["maven_coordinates=com.google.dagger:dagger-android-support:" + POM_VERSION],
-    deps = [
-        ":manual-maven-deps",
-        "//:dagger_with_compiler",
-        "//java/dagger/android",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-    ],
-)
-
-# Our pom.xml generator does not have a way to add manual maven deps. This target exports the
-# targets that don't have the necessary maven_coordinates tags.
-android_library(
-    name = "manual-maven-deps",
-    tags = [
-        "maven_coordinates=com.android.support:appcompat-v7:25.0.0",
-        "maven_coordinates=com.android.support:support-annotations:25.0.0",
-        "maven_coordinates=com.android.support:support-fragment:25.0.0",
-    ],
-    visibility = ["//visibility:private"],
-    exports = [
-        "@androidsdk//com.android.support:appcompat-v7-25.0.0",
-        "@androidsdk//com.android.support:support-annotations-25.0.0",
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-android-support",
-    artifact_name = "Dagger Android Support",
-    packaging = "aar",
-    targets = [":support"],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "support-javadoc",
-    srcs = [":support-srcs"],
-    android_api_level = 26,
-    root_packages = ["dagger.android.support"],
-    deps = [":support"],
-)
diff --git a/java/dagger/android/support/DaggerAppCompatActivity.java b/java/dagger/android/support/DaggerAppCompatActivity.java
deleted file mode 100644
index ccc4faa..0000000
--- a/java/dagger/android/support/DaggerAppCompatActivity.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import dagger.android.AndroidInjection;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * An {@link AppCompatActivity} that injects its members in {@link #onCreate(Bundle)} and can be
- * used to inject {@code Fragment}s attached to it.
- */
-@Beta
-public abstract class DaggerAppCompatActivity extends AppCompatActivity
-    implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  protected void onCreate(@Nullable Bundle savedInstanceState) {
-    AndroidInjection.inject(this);
-    super.onCreate(savedInstanceState);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/support/DaggerAppCompatDialogFragment.java b/java/dagger/android/support/DaggerAppCompatDialogFragment.java
deleted file mode 100644
index 1efaeec..0000000
--- a/java/dagger/android/support/DaggerAppCompatDialogFragment.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import android.content.Context;
-import android.support.v4.app.Fragment;
-import android.support.v7.app.AppCompatDialogFragment;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * An {@link AppCompatDialogFragment} that injects its members in {@link #onAttach(Context)} and can
- * be used to inject child {@link Fragment}s attached to it. Note that when this fragment gets
- * reattached, its members will be injected again.
- */
-@Beta
-public abstract class DaggerAppCompatDialogFragment extends AppCompatDialogFragment
-    implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onAttach(Context context) {
-    AndroidSupportInjection.inject(this);
-    super.onAttach(context);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/support/DaggerApplication.java b/java/dagger/android/support/DaggerApplication.java
deleted file mode 100644
index 1cb3bd8..0000000
--- a/java/dagger/android/support/DaggerApplication.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import dagger.android.AndroidInjector;
-
-/**
- * An {@link Application} that injects its members and can be used to inject classes that the
- * Android framework instantiates. Injection is performed in {@link #onCreate()} or the first call
- * to {@link AndroidInjection#inject(ContentProvider)}, whichever happens first.
- */
-// TODO(ronshapiro): deprecate and remove this class
-public abstract class DaggerApplication extends dagger.android.DaggerApplication {
-  @Override
-  protected abstract AndroidInjector<? extends DaggerApplication> applicationInjector();
-}
diff --git a/java/dagger/android/support/DaggerDialogFragment.java b/java/dagger/android/support/DaggerDialogFragment.java
deleted file mode 100644
index 69b90bc..0000000
--- a/java/dagger/android/support/DaggerDialogFragment.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.support;
-
-import android.content.Context;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * A {@link DialogFragment} that injects its members in {@link #onAttach(Context)} and can be used
- * to inject child {@link Fragment}s attached to it. Note that when this fragment gets reattached,
- * its members will be injected again.
- */
-@Beta
-public abstract class DaggerDialogFragment extends DialogFragment implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onAttach(Context context) {
-    AndroidSupportInjection.inject(this);
-    super.onAttach(context);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/support/DaggerFragment.java b/java/dagger/android/support/DaggerFragment.java
deleted file mode 100644
index 332cdaa..0000000
--- a/java/dagger/android/support/DaggerFragment.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import android.content.Context;
-import android.support.v4.app.Fragment;
-import dagger.android.AndroidInjector;
-import dagger.android.DispatchingAndroidInjector;
-import dagger.android.HasAndroidInjector;
-import dagger.internal.Beta;
-import javax.inject.Inject;
-
-/**
- * A {@link Fragment} that injects its members in {@link #onAttach(Context)} and can be used to
- * inject child {@link Fragment}s attached to it. Note that when this fragment gets reattached, its
- * members will be injected again.
- */
-@Beta
-public abstract class DaggerFragment extends Fragment implements HasAndroidInjector {
-
-  @Inject DispatchingAndroidInjector<Object> androidInjector;
-
-  @Override
-  public void onAttach(Context context) {
-    AndroidSupportInjection.inject(this);
-    super.onAttach(context);
-  }
-
-  @Override
-  public AndroidInjector<Object> androidInjector() {
-    return androidInjector;
-  }
-}
diff --git a/java/dagger/android/support/HasSupportFragmentInjector.java b/java/dagger/android/support/HasSupportFragmentInjector.java
deleted file mode 100644
index e80609e..0000000
--- a/java/dagger/android/support/HasSupportFragmentInjector.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support;
-
-import android.support.v4.app.Fragment;
-import dagger.android.AndroidInjector;
-import dagger.internal.Beta;
-
-/** Provides an {@link AndroidInjector} of {@link Fragment}s. */
-@Beta
-public interface HasSupportFragmentInjector {
-
-  /** Returns an {@link AndroidInjector} of {@link Fragment}s. */
-  AndroidInjector<Fragment> supportFragmentInjector();
-}
diff --git a/java/dagger/android/support/package-info.java b/java/dagger/android/support/package-info.java
deleted file mode 100644
index d49d44d..0000000
--- a/java/dagger/android/support/package-info.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-@CheckReturnValue
-package dagger.android.support;
-
-/**
- * Additions to the APIs in {@link dagger.android} for use with the <a
- * href="https://developer.android.com/topic/libraries/support-library">Android support
- * libraries</a>.
- */
-
-import com.google.errorprone.annotations.CheckReturnValue;
diff --git a/java/dagger/errorprone/AndroidSupportInjectionModuleMigrator.java b/java/dagger/errorprone/AndroidSupportInjectionModuleMigrator.java
deleted file mode 100644
index e98fe9b..0000000
--- a/java/dagger/errorprone/AndroidSupportInjectionModuleMigrator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 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.errorprone;
-
-import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
-
-import com.google.errorprone.BugPattern;
-import com.google.errorprone.BugPattern.ProvidesFix;
-import com.google.errorprone.VisitorState;
-import com.google.errorprone.bugpatterns.BugChecker;
-import com.google.errorprone.bugpatterns.BugChecker.MemberSelectTreeMatcher;
-import com.google.errorprone.fixes.SuggestedFix;
-import com.google.errorprone.matchers.Description;
-import com.google.errorprone.matchers.Matcher;
-import com.google.errorprone.matchers.Matchers;
-import com.google.errorprone.util.ASTHelpers;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.tools.javac.code.Symbol;
-
-/** A refactoring to update AndroidInjector bindings to their new form. */
-@BugPattern(
-    name = "AndroidSupportInjectionModuleMigrator",
-    providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION,
-    summary = "Inlines usages of AndroidSupportInjectionModule to AndroidInjectionModule",
-    explanation =
-        "AndroidSupportInjectionModule is now an empty module and acts as an alias for "
-            + "AndroidInjectionModule. This migration rewrites usages of the former to the latter.",
-    severity = SUGGESTION)
-public final class AndroidSupportInjectionModuleMigrator extends BugChecker
-    implements MemberSelectTreeMatcher {
-  private static final Matcher<ExpressionTree> MODULE_CLASS_LITERAL =
-      Matchers.classLiteral(
-          (ExpressionTree expressionTree, VisitorState state) -> {
-            Symbol symbol = ASTHelpers.getSymbol(expressionTree);
-            if (symbol == null) {
-              return false;
-            }
-            return symbol
-                .getQualifiedName()
-                .contentEquals("dagger.android.support.AndroidSupportInjectionModule");
-          });
-
-  @Override
-  public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) {
-    if (MODULE_CLASS_LITERAL.matches(tree, state)) {
-      return describeMatch(
-          tree,
-          SuggestedFix.builder()
-              .replace(tree, "AndroidInjectionModule.class")
-              .addImport("dagger.android.AndroidInjectionModule")
-              .build());
-    }
-    return Description.NO_MATCH;
-  }
-}
diff --git a/java/dagger/errorprone/BUILD b/java/dagger/errorprone/BUILD
deleted file mode 100644
index 408925a..0000000
--- a/java/dagger/errorprone/BUILD
+++ /dev/null
@@ -1,15 +0,0 @@
-# Description:
-#   ErrorProne refactorings and static analysis for Dagger
-
-package(default_visibility = ["//:src"])
-
-java_library(
-    name = "errorprone",
-    srcs = glob(["*.java"]),
-    deps = [
-        "//java/dagger:core",
-        "@bazel_tools//tools/jdk:langtools-neverlink",
-        "@google_bazel_common//third_party/java/error_prone:check_api",
-        "@google_bazel_common//third_party/java/guava",
-    ],
-)
diff --git a/java/dagger/example/android/simple/AndroidManifest.xml b/java/dagger/example/android/simple/AndroidManifest.xml
deleted file mode 100644
index 711fb1e..0000000
--- a/java/dagger/example/android/simple/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="dagger.example.android.simple">
-
-  <uses-sdk
-    android:minSdkVersion="14"
-    android:targetSdkVersion="24"/>
-
-  <application android:name=".SimpleApplication" android:label="@string/appName">
-    <activity android:name=".MainActivity" android:theme="@style/Theme.AppCompat.Light.NoActionBar">
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN" />
-        <category android:name="android.intent.category.LAUNCHER" />
-      </intent-filter>
-    </activity>
-  </application>
-</manifest>
diff --git a/java/dagger/example/android/simple/BUILD b/java/dagger/example/android/simple/BUILD
deleted file mode 100644
index 7396744..0000000
--- a/java/dagger/example/android/simple/BUILD
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   A skeletal application that demonstates wiring for an injected Application and Actiity.
-
-package(default_visibility = ["//:src"])
-
-android_library(
-    name = "simple_lib",
-    srcs = glob(["*.java"]),
-    manifest = "AndroidManifest.xml",
-    resource_files = glob(["res/**"]),
-    deps = [
-        "//:android",
-        "//:android-support",
-        "//:dagger_with_compiler",
-        "@androidsdk//com.android.support:appcompat-v7-25.0.0",
-        "@androidsdk//com.android.support:support-annotations-25.0.0",
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-    ],
-)
-
-android_binary(
-    name = "simple",
-    aapt_version = "aapt",
-    manifest = "AndroidManifest.xml",
-    deps = [
-        ":simple_lib",
-    ],
-)
diff --git a/java/dagger/example/android/simple/BuildModule.java b/java/dagger/example/android/simple/BuildModule.java
deleted file mode 100644
index 40ac8ee..0000000
--- a/java/dagger/example/android/simple/BuildModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.example.android.simple;
-
-import static android.os.Build.MODEL;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class BuildModule {
-  @Provides
-  @Model
-  static String provideModel() {
-    return MODEL;
-  }
-}
diff --git a/java/dagger/example/android/simple/MainActivity.java b/java/dagger/example/android/simple/MainActivity.java
deleted file mode 100644
index f2aab2d..0000000
--- a/java/dagger/example/android/simple/MainActivity.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 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.example.android.simple;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.TextView;
-import dagger.Binds;
-import dagger.android.AndroidInjector;
-import dagger.android.support.DaggerAppCompatActivity;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-import javax.inject.Inject;
-
-/**
- * The main activity application. It can be injected with any binding from both {@link Component}
- * and {@link dagger.example.android.simple.SimpleApplication.Component}.
- */
-public class MainActivity extends DaggerAppCompatActivity {
-  @dagger.Subcomponent
-  interface Component extends AndroidInjector<MainActivity> {
-
-    @dagger.Subcomponent.Builder
-    abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
-  }
-
-  @dagger.Module(subcomponents = Component.class)
-  abstract class Module {
-
-    @Binds
-    @IntoMap
-    @ClassKey(MainActivity.class)
-    abstract AndroidInjector.Factory<?> bind(Component.Builder builder);
-  }
-
-  private static final String TAG = MainActivity.class.getSimpleName();
-
-  @Inject @Model String model;
-
-  @Inject
-  void logInjection() {
-    Log.i(TAG, "Injecting " + MainActivity.class.getSimpleName());
-  }
-
-  @Override
-  protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-
-    setContentView(R.layout.activity_main);
-
-    TextView greeting = (TextView) findViewById(R.id.greeting);
-    String text = getResources().getString(R.string.welcome, model);
-    greeting.setText(text);
-  }
-}
diff --git a/java/dagger/example/android/simple/Model.java b/java/dagger/example/android/simple/Model.java
deleted file mode 100644
index c52bb98..0000000
--- a/java/dagger/example/android/simple/Model.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 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.example.android.simple;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/** Qualifies bindings relating to {@link android.os.Build#MODEL}. */
-@Qualifier
-@Retention(RUNTIME)
-@Documented
-@interface Model {}
diff --git a/java/dagger/example/android/simple/SimpleApplication.java b/java/dagger/example/android/simple/SimpleApplication.java
deleted file mode 100644
index ae3d42d..0000000
--- a/java/dagger/example/android/simple/SimpleApplication.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 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.example.android.simple;
-
-import android.util.Log;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.DaggerApplication;
-import javax.inject.Inject;
-
-/**
- * A simple, skeletal application that demonstrates a dependency-injected application using the
- * utilities in {@code dagger.android}.
- */
-public class SimpleApplication extends DaggerApplication {
-  private static final String TAG = SimpleApplication.class.getSimpleName();
-
-  @dagger.Component(
-      modules = {AndroidInjectionModule.class, MainActivity.Module.class, BuildModule.class})
-  /* @ApplicationScoped and/or @Singleton */
-  interface Component extends AndroidInjector<SimpleApplication> {
-    @dagger.Component.Builder
-    abstract class Builder extends AndroidInjector.Builder<SimpleApplication> {}
-  }
-
-  @Inject
-  void logInjection() {
-    Log.i(TAG, "Injecting " + SimpleApplication.class.getSimpleName());
-  }
-
-  @Override
-  public void onCreate() {
-    super.onCreate();
-  }
-
-  @Override
-  protected AndroidInjector<SimpleApplication> applicationInjector() {
-    return DaggerSimpleApplication_Component.builder().create(this);
-  }
-}
diff --git a/java/dagger/example/android/simple/res/layout/activity_main.xml b/java/dagger/example/android/simple/res/layout/activity_main.xml
deleted file mode 100644
index 37add1f..0000000
--- a/java/dagger/example/android/simple/res/layout/activity_main.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent"
-  android:background="@android:color/background_light">
-
-  <TextView
-    android:id="@+id/greeting"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_alignParentTop="true"
-    android:textColor="@android:color/primary_text_light"
-    style="@style/TextAppearance.AppCompat.Display4"
-    />
-</RelativeLayout>
diff --git a/java/dagger/example/android/simple/res/values/strings.xml b/java/dagger/example/android/simple/res/values/strings.xml
deleted file mode 100644
index c4ba1fd..0000000
--- a/java/dagger/example/android/simple/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="appName">Simple Dagger</string>
-  <string name="welcome">Hello, %s!</string>
-</resources>
\ No newline at end of file
diff --git a/java/dagger/example/spi/BUILD b/java/dagger/example/spi/BUILD
deleted file mode 100644
index 84b4a87..0000000
--- a/java/dagger/example/spi/BUILD
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018 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.
-
-# Description:
-#   An example of the dagger.spi.BindingGraphPlugin usage
-
-package(default_visibility = ["//:src"])
-
-java_plugin(
-    name = "binding-graph-visualizer",
-    srcs = glob(["*.java"]),
-    deps = [
-        "//java/dagger/model",
-        "//java/dagger/spi",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-    ],
-)
diff --git a/java/dagger/example/spi/BindingGraphVisualizer.java b/java/dagger/example/spi/BindingGraphVisualizer.java
deleted file mode 100644
index e83fa2e..0000000
--- a/java/dagger/example/spi/BindingGraphVisualizer.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2017 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.example.spi;
-
-import static java.util.UUID.randomUUID;
-import static java.util.regex.Matcher.quoteReplacement;
-import static java.util.stream.Collectors.groupingBy;
-
-import com.google.auto.service.AutoService;
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterators;
-import com.google.common.graph.EndpointPair;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.squareup.javapoet.ClassName;
-import dagger.model.Binding;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ChildFactoryMethodEdge;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.Edge;
-import dagger.model.BindingGraph.MaybeBinding;
-import dagger.model.BindingGraph.MissingBinding;
-import dagger.model.BindingGraph.Node;
-import dagger.model.BindingGraph.SubcomponentCreatorBindingEdge;
-import dagger.model.BindingKind;
-import dagger.model.ComponentPath;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import javax.annotation.processing.Filer;
-import javax.lang.model.element.TypeElement;
-import javax.tools.FileObject;
-import javax.tools.StandardLocation;
-
-/**
- * Experimental visualizer used as a proof-of-concept for {@link BindingGraphPlugin}.
- *
- * <p>For each component, writes a <a href=http://www.graphviz.org/content/dot-language>DOT file</a>
- * in the same package. The file name is the name of the component type (with enclosing type names,
- * joined by underscores, preceding it), with a {@code .dot} extension.
- *
- * <p>For example, for a nested component type {@code Foo.Bar} this will generate a file {@code
- * Foo_Bar.dot}.
- */
-@AutoService(BindingGraphPlugin.class)
-public final class BindingGraphVisualizer implements BindingGraphPlugin {
-  private Filer filer;
-
-  @Override
-  public void initFiler(Filer filer) {
-    this.filer = filer;
-  }
-
-  /** Graphviz color names to use for binding nodes within each component. */
-  private static final ImmutableList<String> COMPONENT_COLORS =
-      ImmutableList.of(
-          "/set312/1",
-          "/set312/2",
-          "/set312/3",
-          "/set312/4",
-          "/set312/5",
-          "/set312/6",
-          "/set312/7",
-          "/set312/8",
-          "/set312/9",
-          "/set312/10",
-          "/set312/11",
-          "/set312/12");
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    TypeElement componentElement =
-        bindingGraph.rootComponentNode().componentPath().currentComponent();
-    DotGraph graph = new NodesGraph(bindingGraph).graph();
-    ClassName componentName = ClassName.get(componentElement);
-    try {
-      FileObject file =
-          filer
-              .createResource(
-                  StandardLocation.CLASS_OUTPUT,
-                  componentName.packageName(),
-                  Joiner.on('_').join(componentName.simpleNames()) + ".dot",
-                  componentElement);
-      try (PrintWriter writer = new PrintWriter(file.openWriter())) {
-        graph.write(0, writer);
-      }
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private abstract static class Indented {
-
-    abstract void write(int level, PrintWriter writer);
-
-    @CanIgnoreReturnValue
-    PrintWriter indent(int level, PrintWriter writer) {
-      writer.print(Strings.repeat(" ", level * 2));
-      return writer;
-    }
-  }
-
-  static class DotGraph extends Indented {
-    private final String header;
-    private final List<Indented> elements = new ArrayList<>();
-
-    DotGraph(String header) {
-      this.header = header;
-    }
-
-    @CanIgnoreReturnValue
-    DotGraph add(Indented element) {
-      elements.add(element);
-      return this;
-    }
-
-    @Override
-    void write(int level, PrintWriter writer) {
-      indent(level, writer);
-      writer.println(header + " {");
-      for (Indented element : elements) {
-        element.write(level + 1, writer);
-      }
-      indent(level, writer);
-      writer.println("}");
-    }
-  }
-
-  static class DotStatement<S extends DotStatement<S>> extends Indented {
-    private final String base;
-    private final Map<String, Object> attributes = new LinkedHashMap<>();
-
-    DotStatement(String base) {
-      this.base = base;
-    }
-
-    @SuppressWarnings("unchecked")
-    @CanIgnoreReturnValue
-    S addAttribute(String name, Object value) {
-      attributes.put(name, value);
-      return (S) this;
-    }
-
-    @CanIgnoreReturnValue
-    S addAttributeFormat(String name, String format, Object... args) {
-      return addAttribute(name, String.format(format, args));
-    }
-
-    @Override
-    void write(int level, PrintWriter writer) {
-      indent(level, writer);
-      writer.print(base);
-      if (!attributes.isEmpty()) {
-        writer.print(
-            attributes
-                .entrySet()
-                .stream()
-                .map(
-                    entry ->
-                        String.format("%s=%s", entry.getKey(), quote(entry.getValue().toString())))
-                .collect(Collectors.joining(", ", " [", "]")));
-      }
-      writer.println();
-    }
-  }
-
-  private static String quote(String string) {
-    return '"' + string.replaceAll("\"", quoteReplacement("\\\"")) + '"';
-  }
-
-  static class DotNode extends DotStatement<DotNode> {
-    DotNode(Object nodeName) {
-      super(quote(nodeName.toString()));
-    }
-  }
-
-  static class DotEdge extends DotStatement<DotEdge> {
-    DotEdge(Object leftNode, Object rightNode) {
-      super(quote(leftNode.toString()) + " -> " + quote(rightNode.toString()));
-    }
-  }
-
-  static class NodesGraph {
-    private final DotGraph graph =
-        new DotGraph("digraph")
-            .add(
-                new DotStatement<>("graph")
-                    .addAttribute("rankdir", "LR")
-                    .addAttribute("labeljust", "l")
-                    .addAttribute("compound", true));
-
-    private final BindingGraph bindingGraph;
-    private final Map<Node, UUID> nodeIds = new HashMap<>();
-
-    NodesGraph(BindingGraph bindingGraph) {
-      this.bindingGraph = bindingGraph;
-    }
-
-    DotGraph graph() {
-      if (nodeIds.isEmpty()) {
-        Iterator<String> colors = Iterators.cycle(COMPONENT_COLORS);
-        bindingGraph.network().nodes().stream()
-            .collect(groupingBy(Node::componentPath))
-            .forEach(
-                (component, networkNodes) -> {
-                  DotGraph subgraph = subgraph(component);
-                  subgraph.add(
-                      new DotStatement<>("node")
-                          .addAttribute("style", "filled")
-                          .addAttribute("shape", "box")
-                          .addAttribute("fillcolor", colors.next()));
-                  subgraph.add(new DotStatement<>("graph").addAttribute("label", component));
-                  for (Node node : networkNodes) {
-                    subgraph.add(dotNode(node));
-                  }
-                });
-        for (Edge edge : bindingGraph.network().edges()) {
-          dotEdge(edge).ifPresent(graph::add);
-        }
-      }
-      return graph;
-    }
-
-    DotGraph subgraph(ComponentPath component) {
-      DotGraph subgraph = new DotGraph("subgraph " + quote(clusterName(component)));
-      graph.add(subgraph);
-      return subgraph;
-    }
-
-    UUID nodeId(Node node) {
-      return nodeIds.computeIfAbsent(node, n -> randomUUID());
-    }
-
-    Optional<DotEdge> dotEdge(Edge edge) {
-      EndpointPair<Node> incidentNodes = bindingGraph.network().incidentNodes(edge);
-      DotEdge dotEdge = new DotEdge(nodeId(incidentNodes.source()), nodeId(incidentNodes.target()));
-      if (edge instanceof DependencyEdge) {
-        if (((DependencyEdge) edge).isEntryPoint()) {
-          return Optional.empty();
-        }
-      } else if (edge instanceof ChildFactoryMethodEdge) {
-        dotEdge.addAttribute("style", "dashed");
-        dotEdge.addAttribute("lhead", clusterName(incidentNodes.target().componentPath()));
-        dotEdge.addAttribute("ltail", clusterName(incidentNodes.source().componentPath()));
-        dotEdge.addAttribute("taillabel", ((ChildFactoryMethodEdge) edge).factoryMethod());
-      } else if (edge instanceof SubcomponentCreatorBindingEdge) {
-        dotEdge.addAttribute("style", "dashed");
-        dotEdge.addAttribute("lhead", clusterName(incidentNodes.target().componentPath()));
-        dotEdge.addAttribute("taillabel", "subcomponent");
-      }
-      return Optional.of(dotEdge);
-    }
-
-    DotNode dotNode(Node node) {
-      DotNode dotNode = new DotNode(nodeId(node));
-      if (node instanceof MaybeBinding) {
-        dotNode.addAttribute("tooltip", "");
-        if (bindingGraph.entryPointBindings().contains(node)) {
-          dotNode.addAttribute("penwidth", 3);
-        }
-        if (node instanceof Binding) {
-          dotNode.addAttribute("label", label((Binding) node));
-        }
-        if (node instanceof MissingBinding) {
-          dotNode.addAttributeFormat(
-              "label", "missing binding for %s", ((MissingBinding) node).key());
-        }
-      } else {
-        dotNode.addAttribute("style", "invis").addAttribute("shape", "point");
-      }
-      return dotNode;
-    }
-
-    private String label(Binding binding) {
-      if (binding.kind().equals(BindingKind.MEMBERS_INJECTION)) {
-        return String.format("inject(%s)", binding.key());
-      } else if (binding.isProduction()) {
-        return String.format("@Produces %s", binding.key());
-      } else {
-        return binding.key().toString();
-      }
-    }
-
-    private static String clusterName(ComponentPath owningComponentPath) {
-      return "cluster" + owningComponentPath;
-    }
-  }
-}
diff --git a/java/dagger/grpc/server/BUILD b/java/dagger/grpc/server/BUILD
deleted file mode 100644
index 1c57807..0000000
--- a/java/dagger/grpc/server/BUILD
+++ /dev/null
@@ -1,77 +0,0 @@
-# A framework supporting Dagger-injected gRPC servers.
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES")
-load("//tools:maven.bzl", "pom_file", "POM_VERSION")
-
-ANNOTATIONS_SRCS = [
-    "CallScoped.java",
-    "ForGrpcService.java",
-    "GrpcService.java",
-]
-
-java_library(
-    name = "annotations",
-    srcs = ANNOTATIONS_SRCS,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    tags = ["maven_coordinates=com.google.dagger:dagger-grpc-server-annotations:" + POM_VERSION],
-    deps = [
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
-
-# TODO(dpb): Split out the grpc:inprocess and grpc:netty deps into separate libraries.
-java_library(
-    name = "server",
-    srcs = glob(
-        ["*.java"],
-        exclude = ANNOTATIONS_SRCS,
-    ),
-    exported_plugins = ["//java/dagger/grpc/server/processor:plugin"],
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    tags = ["maven_coordinates=com.google.dagger:dagger-grpc-server:" + POM_VERSION],
-    exports = [":annotations"],
-    deps = [
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/grpc:context",
-        "@google_bazel_common//third_party/java/grpc:core",
-        "@google_bazel_common//third_party/java/grpc:netty",
-        "@google_bazel_common//third_party/java/grpc:protobuf",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/protobuf",
-    ],
-)
-
-pom_file(
-    name = "annotations-pom",
-    artifact_id = "dagger-grpc-server-annotations",
-    artifact_name = "Dagger gRPC Server Annotations",
-    targets = [":annotations"],
-)
-
-pom_file(
-    name = "server-pom",
-    artifact_id = "dagger-grpc-server",
-    artifact_name = "Dagger gRPC Server",
-    targets = [":server"],
-)
-
-filegroup(
-    name = "javadoc-srcs",
-    srcs = glob(["*.java"]),
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "javadoc",
-    srcs = [":javadoc-srcs"],
-    root_packages = ["dagger.grpc.server"],
-    deps = [
-        ":annotations",
-        ":server",
-    ],
-)
diff --git a/java/dagger/grpc/server/CallScoped.java b/java/dagger/grpc/server/CallScoped.java
deleted file mode 100644
index 4b9d14f..0000000
--- a/java/dagger/grpc/server/CallScoped.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-/** A scope that lasts as long as a single gRPC {@link io.grpc.ServerCall}. */
-@Retention(RUNTIME)
-@Scope
-@Documented
-public @interface CallScoped {}
diff --git a/java/dagger/grpc/server/CurrentContextModule.java b/java/dagger/grpc/server/CurrentContextModule.java
deleted file mode 100644
index c117537..0000000
--- a/java/dagger/grpc/server/CurrentContextModule.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import dagger.Module;
-import dagger.Provides;
-import io.grpc.Context;
-
-/**
- * Provides the current {@link Context}.
- */
-@Module
-public final class CurrentContextModule {
-
-  @Provides
-  static Context currentContext() {
-    return Context.current();
-  }
-}
diff --git a/java/dagger/grpc/server/ForGrpcService.java b/java/dagger/grpc/server/ForGrpcService.java
deleted file mode 100644
index 33a83ad..0000000
--- a/java/dagger/grpc/server/ForGrpcService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import java.lang.annotation.Documented;
-import javax.inject.Qualifier;
-
-/**
- * Qualifies some per-service types provided by {@link dagger.Module}s generated by {@link
- * GrpcService}.
- */
-@Documented
-@Qualifier
-public @interface ForGrpcService {
-
-  /** The gRPC service class. */
-  Class<?> value();
-}
diff --git a/java/dagger/grpc/server/GrpcCallMetadataModule.java b/java/dagger/grpc/server/GrpcCallMetadataModule.java
deleted file mode 100644
index 8d474d9..0000000
--- a/java/dagger/grpc/server/GrpcCallMetadataModule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import dagger.Module;
-import dagger.Provides;
-import io.grpc.Metadata;
-
-/**
- * Provides {@link Metadata} about a gRPC call.
- */
-@Module
-public final class GrpcCallMetadataModule {
-  private final Metadata metadata;
-
-  public GrpcCallMetadataModule(Metadata metadata) {
-    this.metadata = checkNotNull(metadata);
-  }
-
-  @Provides
-  Metadata provideHeaders() {
-    return metadata;
-  }
-}
diff --git a/java/dagger/grpc/server/GrpcService.java b/java/dagger/grpc/server/GrpcService.java
deleted file mode 100644
index a746195..0000000
--- a/java/dagger/grpc/server/GrpcService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-/**
- * Annotates a class that implements a gRPC service.
- *
- * <p>Generates several types when annotating a class {@code Foo}:
- *
- * <ul>
- * <li>Interfaces {@code FooComponent} and {@code FooComponent.Factory}.
- * <li>{@linkplain dagger.Module Modules} {@code FooGrpcProxyModule} and {@code
- *     FooGrpcServiceModule}.
- * </ul>
- *
- * <p>To use these types to configure a server:
- *
- * <ol>
- * <li>Create a {@linkplain dagger.Subcomponent subcomponent} that implements {@code FooComponent}
- *     and installs {@code FooGrpcServiceModule}.
- * <li>Install {@link NettyServerModule} or another {@link ServerModule} subclass and {@code
- *     FooGrpcProxyModule} into your {@link javax.inject.Singleton @Singleton} {@linkplain
- *     dagger.Component component}.
- * <li>Bind an implementation of {@code FooComponent.Factory} in your {@link
- *     javax.inject.Singleton @Singleton} {@linkplain dagger.Component component}. The
- *     implementation will typically inject the {@link javax.inject.Singleton @Singleton}
- *     {@linkplain dagger.Component component} and call subcomponent factory methods to instantiate
- *     the correct subcomponent.
- * </ol>
- */
-@Documented
-@Target(ElementType.TYPE)
-public @interface GrpcService {
-  /** The class that gRPC generates from the proto service definition. */
-  Class<?> grpcClass();
-}
diff --git a/java/dagger/grpc/server/InProcessServerModule.java b/java/dagger/grpc/server/InProcessServerModule.java
deleted file mode 100644
index fd93382..0000000
--- a/java/dagger/grpc/server/InProcessServerModule.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import dagger.Module;
-import dagger.Provides;
-import io.grpc.Server;
-import io.grpc.ServerBuilder;
-import io.grpc.inprocess.InProcessServerBuilder;
-import javax.inject.Singleton;
-
-/**
- * Installing this module into a {@link Singleton @Singleton} component means the component can
- * provide a {@link Server} that serves {@linkplain InProcessServerBuilder in-process} requests.
- */
-@Module(includes = ServerModule.class)
-public final class InProcessServerModule {
-
-  private final String name;
-
-  private InProcessServerModule(String name) {
-    this.name = checkNotNull(name);
-  }
-
-  /**
-   * Creates a module that provides a server that binds to a given name
-   *
-   * @param name the identity of the server for clients to connect to
-   */
-  public static InProcessServerModule serverNamed(String name) {
-    return new InProcessServerModule(name);
-  }
-
-  @Provides
-  ServerBuilder<?> serverBuilder() {
-    return InProcessServerBuilder.forName(name);
-  }
-}
diff --git a/java/dagger/grpc/server/NettyServerModule.java b/java/dagger/grpc/server/NettyServerModule.java
deleted file mode 100644
index 4361d62..0000000
--- a/java/dagger/grpc/server/NettyServerModule.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import dagger.Module;
-import dagger.Provides;
-import io.grpc.Server;
-import io.grpc.ServerBuilder;
-import io.grpc.netty.NettyServerBuilder;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import javax.inject.Singleton;
-
-/**
- * Installing this module into a {@link Singleton @Singleton} component means the component can
- * provide a {@linkplain NettyServerBuilder Netty}-based {@link Server}.
- */
-@Module(includes = ServerModule.class)
-public final class NettyServerModule {
-
-  private final SocketAddress socketAddress;
-
-  private NettyServerModule(SocketAddress socketAddress) {
-    this.socketAddress = socketAddress;
-  }
-
-  /**
-   * A module that binds to {@code port} on the wildcard address.
-   */
-  public static NettyServerModule bindingToPort(int port) {
-    return new NettyServerModule(new InetSocketAddress(port));
-  }
-
-  /**
-   * A module that binds to {@code socketAddress}.
-   */
-  public static NettyServerModule bindingTo(SocketAddress socketAddress) {
-    return new NettyServerModule(socketAddress);
-  }
-
-  @Provides
-  ServerBuilder<?> serverBuilder() {
-    return NettyServerBuilder.forAddress(socketAddress);
-  }
-}
diff --git a/java/dagger/grpc/server/ProxyServerCallHandler.java b/java/dagger/grpc/server/ProxyServerCallHandler.java
deleted file mode 100644
index 751d8ca..0000000
--- a/java/dagger/grpc/server/ProxyServerCallHandler.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import io.grpc.Metadata;
-import io.grpc.MethodDescriptor;
-import io.grpc.MethodDescriptor.Marshaller;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerMethodDefinition;
-import io.grpc.ServerServiceDefinition;
-import io.grpc.Status;
-import java.io.InputStream;
-
-/**
- * A {@link ServerCallHandler} that handles calls for a particular method by delegating to a handler
- * in a {@link ServerServiceDefinition} returned by a factory.
- *
- * @param <RequestT> the type of the request payloads
- * @param <ResponseT> the type of the response payloads
- */
-public final class ProxyServerCallHandler<RequestT, ResponseT>
-    implements ServerCallHandler<InputStream, InputStream> {
-
-  /**
-   * A factory for the {@link ServerServiceDefinition} that a {@link ProxyServerCallHandler}
-   * delegates to.
-   */
-  public interface ServiceDefinitionFactory {
-    /**
-     * Returns a service definition that contains a {@link ServerCallHandler} for the
-     * {@link ProxyServerCallHandler}'s method.
-     */
-    ServerServiceDefinition getServiceDefinition(Metadata headers);
-  }
-
-  private final MethodDescriptor<RequestT, ResponseT> delegateMethodDescriptor;
-  private final ServiceDefinitionFactory delegateServiceDefinitionFactory;
-
-  /**
-   * Returns a proxy method definition for {@code methodDescriptor}.
-   *
-   * @param delegateServiceDefinitionFactory factory for the delegate service definition
-   */
-  public static <RequestT, ResponseT> ServerMethodDefinition<InputStream, InputStream> proxyMethod(
-      MethodDescriptor<RequestT, ResponseT> delegateMethodDescriptor,
-      ServiceDefinitionFactory delegateServiceDefinitionFactory) {
-    return ServerMethodDefinition.create(
-        MethodDescriptor.create(
-            delegateMethodDescriptor.getType(),
-            delegateMethodDescriptor.getFullMethodName(),
-            IDENTITY_MARSHALLER,
-            IDENTITY_MARSHALLER),
-        new ProxyServerCallHandler<>(delegateMethodDescriptor, delegateServiceDefinitionFactory));
-  }
-
-  ProxyServerCallHandler(
-      MethodDescriptor<RequestT, ResponseT> delegateMethodDescriptor,
-      ServiceDefinitionFactory delegateServiceDefinitionFactory) {
-    this.delegateMethodDescriptor = delegateMethodDescriptor;
-    this.delegateServiceDefinitionFactory = delegateServiceDefinitionFactory;
-  }
-
-  @Override
-  public Listener<InputStream> startCall(
-      ServerCall<InputStream, InputStream> call,
-      Metadata headers) {
-    ServerMethodDefinition<RequestT, ResponseT> delegateMethod = getMethodDefinition(headers);
-    Listener<RequestT> delegateListener =
-        delegateMethod
-            .getServerCallHandler()
-            .startCall(new ServerCallAdapter(call, delegateMethod.getMethodDescriptor()), headers);
-    return new ServerCallListenerAdapter(delegateListener);
-  }
-
-  @SuppressWarnings("unchecked") // Method definition is the correct type.
-  private ServerMethodDefinition<RequestT, ResponseT> getMethodDefinition(Metadata headers) {
-    String fullMethodName = delegateMethodDescriptor.getFullMethodName();
-    for (ServerMethodDefinition<?, ?> methodDefinition :
-        delegateServiceDefinitionFactory.getServiceDefinition(headers).getMethods()) {
-      if (methodDefinition.getMethodDescriptor().getFullMethodName().equals(fullMethodName)) {
-        return (ServerMethodDefinition<RequestT, ResponseT>) methodDefinition;
-      }
-    }
-    throw new IllegalStateException("Could not find " + fullMethodName);
-  }
-
-  private static final Marshaller<InputStream> IDENTITY_MARSHALLER =
-      new Marshaller<InputStream>() {
-        @Override
-        public InputStream stream(InputStream value) {
-          return value;
-        }
-
-        @Override
-        public InputStream parse(InputStream stream) {
-          return stream;
-        }
-      };
-
-  /** A {@link Listener} that adapts {@code Listener<RequestT>} to {@code Listener<InputStream>}. */
-  private final class ServerCallListenerAdapter extends Listener<InputStream> {
-
-    private final Listener<RequestT> delegate;
-
-    public ServerCallListenerAdapter(Listener<RequestT> delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public void onMessage(InputStream message) {
-      delegate.onMessage(delegateMethodDescriptor.parseRequest(message));
-    }
-
-    @Override
-    public void onHalfClose() {
-      delegate.onHalfClose();
-    }
-
-    @Override
-    public void onCancel() {
-      delegate.onCancel();
-    }
-
-    @Override
-    public void onComplete() {
-      delegate.onComplete();
-    }
-  }
-
-  /**
-   * A {@link ServerCall} that adapts {@code ServerCall<InputStream>} to {@code
-   * ServerCall<ResponseT>}.
-   */
-  final class ServerCallAdapter extends ServerCall<RequestT, ResponseT> {
-
-    private final ServerCall<InputStream, InputStream> delegate;
-    private final MethodDescriptor<RequestT, ResponseT> method;
-
-    ServerCallAdapter(ServerCall<InputStream, InputStream> delegate,
-        MethodDescriptor<RequestT, ResponseT> method) {
-      this.delegate = delegate;
-      this.method = method;
-    }
-
-    @Override
-    public MethodDescriptor<RequestT, ResponseT> getMethodDescriptor() {
-      return method;
-    }
-
-    @Override
-    public void request(int numMessages) {
-      delegate.request(numMessages);
-    }
-
-    @Override
-    public void sendHeaders(Metadata headers) {
-      delegate.sendHeaders(headers);
-    }
-
-    @Override
-    public void sendMessage(ResponseT message) {
-      delegate.sendMessage(delegateMethodDescriptor.streamResponse(message));
-    }
-
-    @Override
-    public void close(Status status, Metadata trailers) {
-      delegate.close(status, trailers);
-    }
-
-    @Override
-    public boolean isCancelled() {
-      return delegate.isCancelled();
-    }
-  }
-}
diff --git a/java/dagger/grpc/server/README.md b/java/dagger/grpc/server/README.md
deleted file mode 100644
index 5fe8d5c..0000000
--- a/java/dagger/grpc/server/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Dagger-gRPC on the Server
-
-This package contains the public types used to create gRPC server applications
-using https://dagger.dev.
-
-It is maintained by the Dagger team.
-
-It is in development, and is planned for open-source release as part of Dagger.
-
-See user documentation at https://dagger.dev/grpc.
diff --git a/java/dagger/grpc/server/ServerModule.java b/java/dagger/grpc/server/ServerModule.java
deleted file mode 100644
index f03f997..0000000
--- a/java/dagger/grpc/server/ServerModule.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server;
-
-import dagger.Module;
-import dagger.Provides;
-import io.grpc.Server;
-import io.grpc.ServerBuilder;
-import io.grpc.ServerServiceDefinition;
-import java.util.Set;
-import javax.inject.Singleton;
-
-/**
- * Provides a {@link Singleton @Singleton} {@link Server}.
- */
-@Module
-public final class ServerModule {
-
-  @Provides
-  @Singleton
-  static Server provideServer(
-      ServerBuilder<?> serverBuilder, Set<ServerServiceDefinition> serviceDefinitions) {
-    for (ServerServiceDefinition serverServiceDefinition : serviceDefinitions) {
-      serverBuilder.addService(serverServiceDefinition);
-    }
-    return serverBuilder.build();
-  }
-}
diff --git a/java/dagger/grpc/server/processor/BUILD b/java/dagger/grpc/server/processor/BUILD
deleted file mode 100644
index ce02b06..0000000
--- a/java/dagger/grpc/server/processor/BUILD
+++ /dev/null
@@ -1,49 +0,0 @@
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//tools:maven.bzl", "pom_file", "POM_VERSION")
-
-java_library(
-    name = "processor",
-    srcs = glob(["*.java"]),
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    tags = ["maven_coordinates=com.google.dagger:dagger-grpc-server-processor:" + POM_VERSION],
-    deps = [
-        "//:dagger_with_compiler",
-        "//java/dagger/grpc/server:annotations",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/google_java_format",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/jsr250_annotations",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-grpc-server-processor",
-    artifact_name = "Dagger gRPC Server Processor",
-    targets = [":processor"],
-)
-
-java_plugin(
-    name = "plugin",
-    generates_api = 1,
-    processor_class = "dagger.grpc.server.processor.GrpcServiceProcessor",
-    deps = [":processor"],
-)
-
-filegroup(
-    name = "javadoc-srcs",
-    srcs = glob(["*.java"]),
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "javadoc",
-    srcs = [":javadoc-srcs"],
-    root_packages = ["dagger.grpc.server.processor"],
-    deps = [":processor"],
-)
diff --git a/java/dagger/grpc/server/processor/GrpcServiceModel.java b/java/dagger/grpc/server/processor/GrpcServiceModel.java
deleted file mode 100644
index 65d6903..0000000
--- a/java/dagger/grpc/server/processor/GrpcServiceModel.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
-import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;
-import static com.google.auto.common.MoreElements.getAnnotationMirror;
-import static com.google.common.base.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Joiner;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import dagger.grpc.server.ForGrpcService;
-import dagger.grpc.server.GrpcService;
-import dagger.grpc.server.processor.SourceGenerator.IoGrpc;
-import java.util.Optional;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleAnnotationValueVisitor7;
-import javax.lang.model.util.Types;
-import javax.tools.Diagnostic.Kind;
-
-class GrpcServiceModel {
-
-  private static final String GRPC_SERVICE_PARAMETER_NAME = "grpcClass";
-
-  private final Types types;
-  private final Elements elements;
-  private final SourceVersion sourceVersion;
-  private final Messager messager;
-  final TypeElement serviceImplementation;
-  final ClassName serviceImplementationClassName;
-  final ClassName serviceDefinitionTypeName;
-  final ClassName proxyModuleName;
-  final ClassName serviceDefinitionTypeFactoryName;
-  final ClassName serviceModuleName;
-  final ClassName unscopedServiceModuleName;
-
-  GrpcServiceModel(ProcessingEnvironment processingEnv, TypeElement serviceImplementation) {
-    this.types = processingEnv.getTypeUtils();
-    this.elements = processingEnv.getElementUtils();
-    this.sourceVersion = processingEnv.getSourceVersion();
-    this.messager = processingEnv.getMessager();
-    this.serviceImplementation = serviceImplementation;
-    this.serviceImplementationClassName = ClassName.get(serviceImplementation);
-    this.serviceDefinitionTypeName = peerClassWithSuffix("ServiceDefinition");
-    this.serviceDefinitionTypeFactoryName = serviceDefinitionTypeName.nestedClass("Factory");
-    this.proxyModuleName = peerClassWithSuffix("GrpcProxyModule");
-    this.serviceModuleName = peerClassWithSuffix("GrpcServiceModule");
-    this.unscopedServiceModuleName = peerClassWithSuffix("UnscopedGrpcServiceModule");
-  }
-
-  /**
-   * Returns the name of a top-level class in the same package as the service implementation
-   * class, whose name is the simple name of the service implementation class and its enclosing
-   * classes, joined with underscores, and appended with {@code suffix}.
-   */
-  private ClassName peerClassWithSuffix(String suffix) {
-    return serviceImplementationClassName.peerClass(
-        Joiner.on('_').join(serviceImplementationClassName.simpleNames()) + suffix);
-  }
-
-  String packageName() {
-    return serviceImplementationClassName.packageName();
-  }
-
-  public boolean validate() {
-    AnnotationValue argument =
-        getAnnotationValue(grpcServiceAnnotation(), GRPC_SERVICE_PARAMETER_NAME);
-    return argument.accept(
-        new SimpleAnnotationValueVisitor7<Boolean, AnnotationValue>(false) {
-          @Override
-          public Boolean visitType(TypeMirror type, AnnotationValue value) {
-            return validateGrpcClass(type, value);
-          }
-        },
-        argument);
-  }
-
-  private AnnotationMirror grpcServiceAnnotation() {
-    return getAnnotationMirror(serviceImplementation, GrpcService.class).get();
-  }
-
-  /** Returns the gRPC service class declared by {@link GrpcService#grpcClass()}. */
-  protected final TypeElement grpcClass() {
-    AnnotationValue argument =
-        getAnnotationValue(grpcServiceAnnotation(), GRPC_SERVICE_PARAMETER_NAME);
-    return GET_TYPE_ELEMENT_FROM_VALUE.visit(argument, argument);
-  }
-
-  /**
-   * Returns the annotation spec for the {@code @Generated} annotation to add to any
-   * type generated by this processor.
-   */
-  protected final Optional<AnnotationSpec> generatedAnnotation() {
-    return generatedAnnotationSpec(
-        elements,
-        sourceVersion,
-        GrpcService.class,
-        String.format(
-            "@%s annotation on %s",
-            GrpcService.class.getCanonicalName(), serviceImplementationClassName));
-  }
-
-  /**
-   * Returns the annotation spec for a {@link ForGrpcService} annotation whose value is the
-   * gRPC-generated service class.
-   */
-  protected final AnnotationSpec forGrpcService() {
-    return AnnotationSpec.builder(ForGrpcService.class)
-        .addMember("value", "$T.class", grpcClass())
-        .build();
-  }
-
-  protected final String subcomponentServiceDefinitionMethodName() {
-    return UPPER_CAMEL.to(LOWER_CAMEL, simpleServiceName()) + "ServiceDefinition";
-  }
-
-  private String simpleServiceName() {
-    return grpcClass().getSimpleName().toString().replaceFirst("Grpc$", "");
-  }
-
-  private TypeElement serviceImplBase(TypeMirror service) {
-    ClassName serviceClassName = ClassName.get(MoreTypes.asTypeElement(service));
-    ClassName serviceImplBaseName = serviceClassName.nestedClass(simpleServiceName() + "ImplBase");
-    return elements.getTypeElement(serviceImplBaseName.toString());
-  }
-
-  private boolean validateGrpcClass(TypeMirror type, AnnotationValue value) {
-    TypeElement serviceImplBase = serviceImplBase(type);
-    if (serviceImplBase == null || !types.isSubtype(serviceImplBase.asType(), bindableService())) {
-      messager.printMessage(
-          Kind.ERROR,
-          String.format("%s is not a gRPC service class", type),
-          serviceImplementation,
-          grpcServiceAnnotation(),
-          value);
-      return false;
-    }
-    if (!(types.isSubtype(serviceImplementation.asType(), serviceImplBase.asType()))) {
-      messager.printMessage(
-          Kind.ERROR,
-          String.format(
-              "%s must extend %s", serviceImplementation, serviceImplBase.getQualifiedName()),
-          serviceImplementation,
-          grpcServiceAnnotation(),
-          value);
-      return false;
-    }
-    return true;
-  }
-
-  private TypeMirror bindableService() {
-    return elements.getTypeElement(IoGrpc.BINDABLE_SERVICE.toString()).asType();
-  }
-
-  static final AnnotationValueVisitor<TypeElement, AnnotationValue> GET_TYPE_ELEMENT_FROM_VALUE =
-      new SimpleAnnotationValueVisitor7<TypeElement, AnnotationValue>() {
-        @Override
-        public TypeElement visitType(TypeMirror t, AnnotationValue p) {
-          return MoreTypes.asTypeElement(t);
-        }
-
-        @Override
-        protected TypeElement defaultAction(Object o, AnnotationValue p) {
-          throw new IllegalArgumentException("Expected " + p + " to be a class");
-        }
-      };
-}
diff --git a/java/dagger/grpc/server/processor/GrpcServiceModuleGenerator.java b/java/dagger/grpc/server/processor/GrpcServiceModuleGenerator.java
deleted file mode 100644
index bbad143..0000000
--- a/java/dagger/grpc/server/processor/GrpcServiceModuleGenerator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static com.squareup.javapoet.WildcardTypeName.subtypeOf;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.grpc.server.GrpcService;
-import java.util.List;
-
-/**
- * An object that generates the non-proxying service definition module for a {@link
- * GrpcService}-annotated service implementation.
- */
-final class GrpcServiceModuleGenerator extends SourceGenerator {
-
-  private static final TypeName LIST_OF_INTERCEPTORS = ParameterizedTypeName.get(
-      ClassName.get(List.class), subtypeOf(IoGrpc.SERVER_INTERCEPTOR));
-  
-  private final GrpcServiceModel grpcServiceModel;
-
-  GrpcServiceModuleGenerator(GrpcServiceModel grpcServiceModel) {
-    super(grpcServiceModel.packageName());
-    this.grpcServiceModel = grpcServiceModel;
-  }
-
-  @Override
-  protected TypeSpec createType() {
-    TypeSpec.Builder serviceModule =
-        classBuilder(grpcServiceModel.serviceModuleName)
-            .addJavadoc(
-                "Install this module in the {@link $T @Singleton} server component\n",
-                JavaxInject.singleton().type)
-            .addJavadoc(
-                "or in the subcomponent that implements {@link $T}.\n",
-                grpcServiceModel.serviceDefinitionTypeName);
-    grpcServiceModel.generatedAnnotation().ifPresent(serviceModule::addAnnotation);
-    return serviceModule
-        .addAnnotation(Dagger.module())
-        .addModifiers(PUBLIC, FINAL)
-        .addMethod(provideServiceDefinition())
-        .build();
-  }
-
-  /**
-   * Returns the {@link dagger.Provides @Provides} method for the {@link
-   * io.grpc.ServerServiceDefinition} for the service.
-   */
-  private MethodSpec provideServiceDefinition() {
-    return methodBuilder("serviceDefinition")
-        .addAnnotation(Dagger.provides())
-        .addAnnotation(grpcServiceModel.forGrpcService())
-        .addModifiers(STATIC)
-        .returns(IoGrpc.SERVER_SERVICE_DEFINITION)
-        .addParameter(grpcServiceModel.serviceImplementationClassName, "implementation")
-        .addParameter(
-            ParameterSpec.builder(LIST_OF_INTERCEPTORS, "interceptors")
-                .addAnnotation(grpcServiceModel.forGrpcService())
-                .build())
-        .addStatement(
-            "$T serviceDefinition = implementation.bindService()", IoGrpc.SERVER_SERVICE_DEFINITION)
-        .addStatement(
-            "return $T.intercept(serviceDefinition, interceptors)", IoGrpc.SERVER_INTERCEPTORS)
-        .build();
-  }
-}
diff --git a/java/dagger/grpc/server/processor/GrpcServiceProcessor.java b/java/dagger/grpc/server/processor/GrpcServiceProcessor.java
deleted file mode 100644
index e361fdb..0000000
--- a/java/dagger/grpc/server/processor/GrpcServiceProcessor.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static javax.lang.model.util.ElementFilter.typesIn;
-
-import com.google.auto.common.BasicAnnotationProcessor;
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.auto.service.AutoService;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.SetMultimap;
-import com.google.googlejavaformat.java.filer.FormattingFiler;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.JavaFile;
-import dagger.grpc.server.GrpcService;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Processor;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic.Kind;
-
-/**
- * Generates code from types annotated with {@link GrpcService @GrpcService}.
- *
- * @see <a href="https://dagger.dev/grpc">https://dagger.dev/grpc</a>
- */
-@AutoService(Processor.class)
-public class GrpcServiceProcessor extends BasicAnnotationProcessor implements ProcessingStep {
-
-  @Override
-  protected ImmutableList<GrpcServiceProcessor> initSteps() {
-    return ImmutableList.of(this);
-  }
-
-  @Override
-  public ImmutableSet<Class<GrpcService>> annotations() {
-    return ImmutableSet.of(GrpcService.class);
-  }
-
-  @Override
-  public SourceVersion getSupportedSourceVersion() {
-    return SourceVersion.latest();
-  }
-
-  @Override
-  public Set<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder();
-    for (TypeElement element : typesIn(elementsByAnnotation.get(GrpcService.class))) {
-      try {
-        GrpcServiceModel grpcServiceModel = new GrpcServiceModel(processingEnv, element);
-        if (grpcServiceModel.validate()) {
-          write(new ServiceDefinitionTypeGenerator(grpcServiceModel), element);
-          write(new ProxyModuleGenerator(grpcServiceModel), element);
-          write(new GrpcServiceModuleGenerator(grpcServiceModel), element);
-          write(new UnscopedGrpcServiceModuleGenerator(grpcServiceModel), element);
-        }
-      } catch (TypeNotPresentException e) {
-        deferredElements.add(element);
-      }
-    }
-    return deferredElements.build();
-  }
-
-  private void write(SourceGenerator grpcServiceTypeWriter, final TypeElement element) {
-    JavaFile javaFile = grpcServiceTypeWriter.javaFile();
-    ClassName outputClassName = ClassName.get(javaFile.packageName, javaFile.typeSpec.name);
-    try {
-      javaFile.writeTo(new FormattingFiler(processingEnv.getFiler()));
-    } catch (IOException e) {
-      processingEnv
-          .getMessager()
-          .printMessage(
-              Kind.ERROR, String.format("Error writing %s: %s", outputClassName, e), element);
-    }
-  }
-}
diff --git a/java/dagger/grpc/server/processor/ProxyModuleGenerator.java b/java/dagger/grpc/server/processor/ProxyModuleGenerator.java
deleted file mode 100644
index 60aea8e..0000000
--- a/java/dagger/grpc/server/processor/ProxyModuleGenerator.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static com.google.auto.common.MoreElements.hasModifiers;
-import static com.google.common.collect.ImmutableList.toImmutableList;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.fieldsIn;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.common.collect.ImmutableList;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.grpc.server.GrpcService;
-import java.util.List;
-import java.util.function.Function;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * An object that generates the proxying service definition module for a {@link
- * GrpcService}-annotated service implementation.
- */
-final class ProxyModuleGenerator extends SourceGenerator {
-
-  private final GrpcServiceModel grpcServiceModel;
-
-  ProxyModuleGenerator(GrpcServiceModel grpcServiceModel) {
-    super(grpcServiceModel.packageName());
-    this.grpcServiceModel = grpcServiceModel;
-  }
-
-  @Override
-  protected TypeSpec createType() {
-    TypeSpec.Builder proxyModule =
-        classBuilder(grpcServiceModel.proxyModuleName)
-            .addModifiers(PUBLIC, FINAL)
-            .addJavadoc(
-                "Install this module in the {@link $T @Singleton} server component.\n",
-                JavaxInject.singleton().type);
-    grpcServiceModel.generatedAnnotation().ifPresent(proxyModule::addAnnotation);
-    return proxyModule
-        .addAnnotation(Dagger.module())
-        .addMethod(provideServiceDefinitionContribution())
-        .addMethod(provideServiceDefinitionFactory())
-        .build();
-  }
-
-  /**
-   * Returns the {@link dagger.Provides @Provides} method for the proxying {@link
-   * io.grpc.ServerServiceDefinition}.
-   */
-  private MethodSpec provideServiceDefinitionContribution() {
-    MethodSpec.Builder method =
-        methodBuilder("serviceDefinition")
-            .addAnnotation(Dagger.provides())
-            .addAnnotation(Dagger.intoSet())
-            .addAnnotation(JavaxInject.singleton())
-            .addModifiers(STATIC)
-            .returns(IoGrpc.SERVER_SERVICE_DEFINITION)
-            .addParameter(
-                ParameterSpec.builder(
-                        Dagger.GrpcServer.SERVICE_DEFINITION_FACTORY, "serviceDefinitionFactory")
-                    .addAnnotation(grpcServiceModel.forGrpcService())
-                    .build())
-            .addCode(
-                "return $T.builder($T.SERVICE_NAME)",
-                IoGrpc.SERVER_SERVICE_DEFINITION,
-                grpcServiceModel.grpcClass());
-    for (CodeBlock methodDescriptor : methodDescriptors()) {
-      method.addCode(
-          ".addMethod($T.proxyMethod($L, serviceDefinitionFactory))",
-          Dagger.GrpcServer.PROXY_SERVER_CALL_HANDLER,
-          methodDescriptor);
-    }
-    method.addCode(".build();");
-    return method.build();
-  }
-
-  /**
-   * Returns the {@link io.grpc.MethodDescriptor} references from the class enclosing the service
-   * interface.
-   *
-   * <p>Looks first for public static methods (new in 1.8), and then for public static fields if it
-   * finds none.
-   */
-  private ImmutableList<CodeBlock> methodDescriptors() {
-    ImmutableList<CodeBlock> staticMethodCalls =
-        findMethodDescriptors(
-            methodsIn(grpcServiceModel.grpcClass().getEnclosedElements()),
-            ExecutableElement::getReturnType,
-            method ->
-                CodeBlock.of("$T.$N()", grpcServiceModel.grpcClass(), method.getSimpleName()));
-    if (!staticMethodCalls.isEmpty()) {
-      return staticMethodCalls;
-    }
-    return findMethodDescriptors(
-        fieldsIn(grpcServiceModel.grpcClass().getEnclosedElements()),
-        VariableElement::asType,
-        field -> CodeBlock.of("$T.$N", grpcServiceModel.grpcClass(), field.getSimpleName()));
-  }
-
-  private <E extends Element> ImmutableList<CodeBlock> findMethodDescriptors(
-      List<E> elements,
-      Function<? super E, TypeMirror> elementType,
-      Function<? super E, CodeBlock> elementReference) {
-    return elements
-        .stream()
-        .filter(hasModifiers(PUBLIC, STATIC)::apply)
-        .filter(
-            method -> {
-              TypeName typeName = TypeName.get(elementType.apply(method));
-              return typeName instanceof ParameterizedTypeName
-                  && ((ParameterizedTypeName) typeName).rawType.equals(IoGrpc.METHOD_DESCRIPTOR);
-            })
-        .map(elementReference)
-        .collect(toImmutableList());
-  }
-
-  /**
-   * Returns the {@link dagger.Provides @Provides} method for the {@link
-   * dagger.grpc.server.ProxyServerCallHandler.ServiceDefinitionFactory} used by the proxy.
-   */
-  private MethodSpec provideServiceDefinitionFactory() {
-    return methodBuilder("serviceDefinitionFactory")
-        .addAnnotation(Dagger.provides())
-        .addAnnotation(grpcServiceModel.forGrpcService())
-        .addModifiers(STATIC)
-        .returns(Dagger.GrpcServer.SERVICE_DEFINITION_FACTORY)
-        .addParameter(grpcServiceModel.serviceDefinitionTypeFactoryName, "factory", FINAL)
-        .addStatement("return $L", anonymousServiceDefinitionFactory())
-        .build();
-  }
-
-  /**
-   * Returns the anonymous inner class that implements the {@link
-   * dagger.grpc.server.ProxyServerCallHandler.ServiceDefinitionFactory} used by the proxy.
-   */
-  private TypeSpec anonymousServiceDefinitionFactory() {
-    return anonymousClassBuilder("")
-        .addSuperinterface(Dagger.GrpcServer.SERVICE_DEFINITION_FACTORY)
-        .addMethod(
-            methodBuilder("getServiceDefinition")
-                .addAnnotation(Override.class)
-                .addModifiers(PUBLIC)
-                .returns(IoGrpc.SERVER_SERVICE_DEFINITION)
-                .addParameter(IoGrpc.METADATA, "headers")
-                .addStatement(
-                    "return factory.grpcService(new $T(headers)).$N()",
-                    Dagger.GrpcServer.GRPC_CALL_METADATA_MODULE,
-                    grpcServiceModel.subcomponentServiceDefinitionMethodName())
-                .build())
-        .build();
-  }
-}
diff --git a/java/dagger/grpc/server/processor/ServiceDefinitionTypeGenerator.java b/java/dagger/grpc/server/processor/ServiceDefinitionTypeGenerator.java
deleted file mode 100644
index 15e13fb..0000000
--- a/java/dagger/grpc/server/processor/ServiceDefinitionTypeGenerator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.interfaceBuilder;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.squareup.javapoet.TypeSpec;
-import dagger.grpc.server.GrpcService;
-
-/**
- * An object that generates the component supertype interface for a {@link GrpcService}-annotated
- * service implementation.
- */
-final class ServiceDefinitionTypeGenerator extends SourceGenerator {
-
-  private final GrpcServiceModel grpcServiceModel;
-
-  ServiceDefinitionTypeGenerator(GrpcServiceModel grpcServiceModel) {
-    super(grpcServiceModel.packageName());
-    this.grpcServiceModel = grpcServiceModel;
-  }
-
-  @Override
-  protected TypeSpec createType() {
-    TypeSpec.Builder type =
-        interfaceBuilder(grpcServiceModel.serviceDefinitionTypeName.simpleName())
-            .addJavadoc("A component must implement this interface.\n")
-            .addModifiers(PUBLIC);
-    grpcServiceModel.generatedAnnotation().ifPresent(type::addAnnotation);
-    type.addType(
-        interfaceBuilder(grpcServiceModel.serviceDefinitionTypeFactoryName.simpleName())
-            .addModifiers(PUBLIC, STATIC)
-            .addMethod(
-                methodBuilder("grpcService")
-                    .addModifiers(PUBLIC, ABSTRACT)
-                    .returns(grpcServiceModel.serviceDefinitionTypeName)
-                    .addParameter(
-                        Dagger.GrpcServer.GRPC_CALL_METADATA_MODULE, "grpcCallMetadataModule")
-                    .build())
-            .build());
-    type.addMethod(
-        methodBuilder(grpcServiceModel.subcomponentServiceDefinitionMethodName())
-            .addModifiers(PUBLIC, ABSTRACT)
-            .returns(IoGrpc.SERVER_SERVICE_DEFINITION)
-            .addAnnotation(grpcServiceModel.forGrpcService())
-            .build());
-    return type.build();
-  }
-}
diff --git a/java/dagger/grpc/server/processor/SourceGenerator.java b/java/dagger/grpc/server/processor/SourceGenerator.java
deleted file mode 100644
index 806d6e6..0000000
--- a/java/dagger/grpc/server/processor/SourceGenerator.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.TypeSpec;
-
-/**
- * An object that generates one top-level type.
- */
-abstract class SourceGenerator {
-
-  private final String packageName;
-
-  protected SourceGenerator(String packageName) {
-    this.packageName = packageName;
-  }
-
-  public JavaFile javaFile() {
-    return JavaFile.builder(packageName, createType()).build();
-  }
-
-  /**
-   * Creates the type to write.
-   */
-  protected abstract TypeSpec createType();
-
-  /** Class names and annotation specs for types in the {@link dagger} package. */
-  protected static final class Dagger {
-    private Dagger() {}
-
-    static AnnotationSpec binds() {
-      return AnnotationSpec.builder(ClassName.get("dagger", "Binds")).build();
-    }
-
-    static AnnotationSpec intoSet() {
-      return AnnotationSpec.builder(ClassName.get("dagger.multibindings", "IntoSet")).build();
-    }
-
-    static AnnotationSpec provides() {
-      return AnnotationSpec.builder(ClassName.get("dagger", "Provides")).build();
-    }
-
-    /** A {@code @dagger.Module} annotation that includes the given module classes. */
-    static AnnotationSpec module(ClassName... includedModules) {
-      AnnotationSpec.Builder module = AnnotationSpec.builder(ClassName.get("dagger", "Module"));
-      for (ClassName includedModule : includedModules) {
-        module.addMember("includes", "$T.class", includedModule);
-      }
-      return module.build();
-    }
-
-    /** Class names and annotation specs for types in the {@link dagger.grpc} package. */
-    protected static final class GrpcServer {
-      private GrpcServer() {}
-
-      static final ClassName PROXY_SERVER_CALL_HANDLER =
-          ClassName.get("dagger.grpc.server", "ProxyServerCallHandler");
-
-      static final ClassName GRPC_CALL_METADATA_MODULE =
-          ClassName.get("dagger.grpc.server", "GrpcCallMetadataModule");
-
-      static final ClassName SERVICE_DEFINITION_FACTORY =
-          PROXY_SERVER_CALL_HANDLER.nestedClass("ServiceDefinitionFactory");
-    }
-  }
-
-  /** Class names and annotation specs for types in the {@link io.grpc} package. */
-  protected static final class IoGrpc {
-    private IoGrpc() {}
-
-    static final ClassName BINDABLE_SERVICE = ClassName.get("io.grpc", "BindableService");
-    static final ClassName METADATA = ClassName.get("io.grpc", "Metadata");
-    static final ClassName METHOD_DESCRIPTOR = ClassName.get("io.grpc", "MethodDescriptor");
-    static final ClassName SERVER_INTERCEPTOR =
-        ClassName.get("io.grpc", "ServerInterceptor");
-    static final ClassName SERVER_INTERCEPTORS =
-        ClassName.get("io.grpc", "ServerInterceptors");
-    static final ClassName SERVER_SERVICE_DEFINITION =
-        ClassName.get("io.grpc", "ServerServiceDefinition");
-  }
-
-  /** Class names and annotation specs for types in the {@link javax.inject} package. */
-  protected static final class JavaxInject {
-    private JavaxInject() {}
-
-    static AnnotationSpec inject() {
-      return AnnotationSpec.builder(ClassName.get("javax.inject", "Inject")).build();
-    }
-
-    static AnnotationSpec singleton() {
-      return AnnotationSpec.builder(ClassName.get("javax.inject", "Singleton")).build();
-    }
-  }
-}
diff --git a/java/dagger/grpc/server/processor/UnscopedGrpcServiceModuleGenerator.java b/java/dagger/grpc/server/processor/UnscopedGrpcServiceModuleGenerator.java
deleted file mode 100644
index 339fb0f..0000000
--- a/java/dagger/grpc/server/processor/UnscopedGrpcServiceModuleGenerator.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.server.processor;
-
-import static com.google.common.base.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-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;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeSpec;
-import dagger.grpc.server.GrpcService;
-
-/**
- * An object that generates the unscoped-proxying service definition module for a {@link
- * GrpcService}-annotated service implementation.
- */
-final class UnscopedGrpcServiceModuleGenerator extends SourceGenerator {
-
-  private final GrpcServiceModel grpcServiceModel;
-
-  UnscopedGrpcServiceModuleGenerator(GrpcServiceModel grpcServiceModel) {
-    super(grpcServiceModel.packageName());
-    this.grpcServiceModel = grpcServiceModel;
-  }
-
-  @Override
-  protected TypeSpec createType() {
-    ClassName unscopedComponentFactory =
-        grpcServiceModel.unscopedServiceModuleName.nestedClass(
-            grpcServiceModel.serviceImplementationClassName.simpleName() + "ComponentFactory");
-    TypeSpec.Builder unscopedServiceModule =
-        classBuilder(grpcServiceModel.unscopedServiceModuleName)
-            .addJavadoc(
-                "Install this module in the {@link $T @Singleton} server component\n",
-                JavaxInject.singleton().type)
-            .addJavadoc(
-                "if it implements {@link $T}.\n", grpcServiceModel.serviceDefinitionTypeName);
-    grpcServiceModel.generatedAnnotation().ifPresent(unscopedServiceModule::addAnnotation);
-    return unscopedServiceModule
-        .addAnnotation(
-            Dagger.module(grpcServiceModel.proxyModuleName, grpcServiceModel.serviceModuleName))
-        .addModifiers(PUBLIC, ABSTRACT)
-        .addType(unscopedComponentFactory(unscopedComponentFactory.simpleName()))
-        .addMethod(bindSubcomponentFactory(unscopedComponentFactory))
-        .addMethod(constructorBuilder().addModifiers(PRIVATE).build())
-        .build();
-  }
-  
-  /**
-   * Returns the class that implements the component factory type by returning the singleton
-   * component itself.
-   */
-  private TypeSpec unscopedComponentFactory(String simpleName) {
-    return TypeSpec.classBuilder(simpleName)
-        .addModifiers(STATIC, FINAL)
-        .addSuperinterface(grpcServiceModel.serviceDefinitionTypeFactoryName)
-        .addField(grpcServiceModel.serviceDefinitionTypeName, "component", PRIVATE, FINAL)
-        .addMethod(
-            MethodSpec.constructorBuilder()
-                .addAnnotation(JavaxInject.inject())
-                .addParameter(grpcServiceModel.serviceDefinitionTypeName, "component")
-                .addStatement("this.component = component")
-                .build())
-        .addMethod(
-            MethodSpec.methodBuilder("grpcService")
-                .addAnnotation(Override.class)
-                .addModifiers(PUBLIC)
-                .returns(grpcServiceModel.serviceDefinitionTypeName)
-                .addParameter(Dagger.GrpcServer.GRPC_CALL_METADATA_MODULE, "grpcCallMetadataModule")
-                .addStatement("return component")
-                .build())
-        .build();
-  }
-
-  /**
-   * Returns the {@link dagger.Binds @Binds} method that binds the component factory type to the
-   * {@linkplain #unscopedComponentFactory(String) unscoped component factory implementation class}.
-   */
-  private MethodSpec bindSubcomponentFactory(ClassName unscopedComponentFactory) {
-    return MethodSpec.methodBuilder(
-            UPPER_CAMEL.to(
-                LOWER_CAMEL, grpcServiceModel.serviceDefinitionTypeFactoryName.simpleName()))
-        .addAnnotation(Dagger.binds())
-        .addModifiers(ABSTRACT)
-        .returns(grpcServiceModel.serviceDefinitionTypeFactoryName)
-        .addParameter(unscopedComponentFactory, "factory")
-        .build();
-  }
-}
diff --git a/java/dagger/internal/AbstractMapFactory.java b/java/dagger/internal/AbstractMapFactory.java
deleted file mode 100644
index 1cf83fa..0000000
--- a/java/dagger/internal/AbstractMapFactory.java
+++ /dev/null
@@ -1,81 +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;
-
-import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize;
-import static dagger.internal.Preconditions.checkNotNull;
-import static java.util.Collections.unmodifiableMap;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import javax.inject.Provider;
-
-/**
- * An {@code abstract} {@link Factory} implementation used to implement {@link Map} bindings.
- *
- * @param <K> the key type of the map that this provides
- * @param <V> the type that each contributing factory
- * @param <V2> the value type of the map that this provides
- */
-abstract class AbstractMapFactory<K, V, V2> implements Factory<Map<K, V2>> {
-  private final Map<K, Provider<V>> contributingMap;
-
-  AbstractMapFactory(Map<K, Provider<V>> map) {
-    this.contributingMap = unmodifiableMap(map);
-  }
-
-  /** The map of {@link Provider}s that contribute to this map binding. */
-  final Map<K, Provider<V>> contributingMap() {
-    return contributingMap;
-  }
-
-  /** A builder for {@link AbstractMapFactory}. */
-  public abstract static class Builder<K, V, V2> {
-    final LinkedHashMap<K, Provider<V>> map;
-
-    Builder(int size) {
-      this.map = newLinkedHashMapWithExpectedSize(size);
-    }
-
-    // Unfortunately, we cannot return a self-type here because a raw Provider type passed to one of
-    // these methods affects the returned type of the method. The first put*() call erases the self
-    // type to the "raw" self type, and the second erases the type to the upper bound
-    // (AbstractMapFactory.Builder), which doesn't have a build() method.
-    //
-    // The methods are therefore not declared public so that each subtype will redeclare them and
-    // expand their accessibility
-
-    /** Associates {@code key} with {@code providerOfValue}. */
-    Builder<K, V, V2> put(K key, Provider<V> providerOfValue) {
-      map.put(checkNotNull(key, "key"), checkNotNull(providerOfValue, "provider"));
-      return this;
-    }
-
-    Builder<K, V, V2> putAll(Provider<Map<K, V2>> mapOfProviders) {
-      if (mapOfProviders instanceof DelegateFactory) {
-        @SuppressWarnings("unchecked")
-        DelegateFactory<Map<K, V2>> asDelegateFactory = (DelegateFactory) mapOfProviders;
-        return putAll(asDelegateFactory.getDelegate());
-      }
-      @SuppressWarnings("unchecked")
-      AbstractMapFactory<K, V, ?> asAbstractMapFactory =
-          ((AbstractMapFactory<K, V, ?>) (Provider) mapOfProviders);
-      map.putAll(asAbstractMapFactory.contributingMap);
-      return this;
-    }
-  }
-}
diff --git a/java/dagger/internal/Beta.java b/java/dagger/internal/Beta.java
deleted file mode 100644
index 2e97f05..0000000
--- a/java/dagger/internal/Beta.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-/**
- * Signifies that a public API (public class, method or field) is subject to
- * incompatible changes, or even removal, in a future release. An API bearing
- * this annotation is exempt from any compatibility guarantees made by its
- * containing library. Note that the presence of this annotation implies nothing
- * about the quality or performance of the API in question, only the fact that
- * it is not "API-frozen."
- */
-@Documented
-@Retention(SOURCE)
-public @interface Beta {}
diff --git a/java/dagger/internal/ComponentDefinitionType.java b/java/dagger/internal/ComponentDefinitionType.java
deleted file mode 100644
index 1ab8b13..0000000
--- a/java/dagger/internal/ComponentDefinitionType.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Target;
-
-/** Specifies the user-defined component that is being implemented by the annotated class. */
-@Target(TYPE)
-public @interface ComponentDefinitionType {
-  Class<?> value();
-}
diff --git a/java/dagger/internal/ConfigureInitializationParameters.java b/java/dagger/internal/ConfigureInitializationParameters.java
deleted file mode 100644
index 1ca0fbb..0000000
--- a/java/dagger/internal/ConfigureInitializationParameters.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-
-import java.lang.annotation.Target;
-
-/**
- * Annotates a {@code configureInitialization()} method with {@code ComponentRequirement}s that it
- * accepts as parameters.
- */
-@Target(METHOD)
-public @interface ConfigureInitializationParameters {
-  /**
-   * The list of parameters.
-   *
-   * Each value is a {@link dagger.internal.codegen.serialization.ComponentRequirementProto}
-   * serialized in Base64.
-   */
-  String[] value() default {};
-}
diff --git a/java/dagger/internal/DaggerCollections.java b/java/dagger/internal/DaggerCollections.java
deleted file mode 100644
index cebca42..0000000
--- a/java/dagger/internal/DaggerCollections.java
+++ /dev/null
@@ -1,89 +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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Collection utility methods in service of Dagger internal classes. <em>Do not use</em> in client
- * code.
- */
-public final class DaggerCollections {
-  /**
-   * The maximum value for a signed 32-bit integer that is equal to a power of 2.
-   */
-  private static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
-
-  private DaggerCollections() {}
-
-  /**
-   * Returns a new list that is pre-sized to {@code size}, or {@link Collections#emptyList()} if
-   * empty. The list returned is never intended to grow beyond {@code size}, so adding to a list
-   * when the size is 0 is an error.
-   */
-  public static <T> List<T> presizedList(int size) {
-    if (size == 0) {
-      return Collections.emptyList();
-    }
-    return new ArrayList<T>(size);
-  }
-
-  /**
-   * Returns true if at least one pair of items in {@code list} are equals.
-   */
-  public static boolean hasDuplicates(List<?> list) {
-    if (list.size() < 2) {
-      return false;
-    }
-    Set<Object> asSet = new HashSet<Object>(list);
-    return list.size() != asSet.size();
-  }
-
-  /**
-   * Creates a {@link HashSet} instance, with a high enough "intial capcity" that it <em>should</em>
-   * hold {@code expectedSize} elements without growth.
-   */
-  static <T> HashSet<T> newHashSetWithExpectedSize(int expectedSize) {
-    return new HashSet<T>(calculateInitialCapacity(expectedSize));
-  }
-
-  /**
-   * Creates a {@link LinkedHashMap} instance, with a high enough "initial capacity" that it
-   * <em>should</em> hold {@code expectedSize} elements without growth.
-   */
-  public static <K, V> LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) {
-    return new LinkedHashMap<K, V>(calculateInitialCapacity(expectedSize));
-  }
-
-  private static int calculateInitialCapacity(int expectedSize) {
-    if (expectedSize < 3) {
-      return expectedSize + 1;
-    }
-    if (expectedSize < MAX_POWER_OF_TWO) {
-      // This is the calculation used in JDK8 to resize when a putAll
-      // happens; it seems to be the most conservative calculation we
-      // can make.  0.75 is the default load factor.
-      return (int) (expectedSize / 0.75F + 1.0F);
-    }
-    return Integer.MAX_VALUE; // any large value
-  }
-}
diff --git a/java/dagger/internal/DelegateFactory.java b/java/dagger/internal/DelegateFactory.java
deleted file mode 100644
index 3b4a30f..0000000
--- a/java/dagger/internal/DelegateFactory.java
+++ /dev/null
@@ -1,70 +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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import javax.inject.Provider;
-
-/**
- * A DelegateFactory that is used to stitch Provider/Lazy indirection based dependency cycles.
- * 
- * @since 2.0.1
- */
-public final class DelegateFactory<T> implements Factory<T> {
-  private Provider<T> delegate;
-
-  @Override
-  public T get() {
-    if (delegate == null) {
-      throw new IllegalStateException();
-    }
-    return delegate.get();
-  }
-
-  // TODO(ronshapiro): remove this once we can reasonably expect generated code is no longer using
-  // this method
-  @Deprecated
-  public void setDelegatedProvider(Provider<T> delegate) {
-    setDelegate(this, delegate);
-  }
-
-  /**
-   * Sets {@code delegateFactory}'s delegate provider to {@code delegate}.
-   *
-   * <p>{@code delegateFactory} must be an instance of {@link DelegateFactory}, otherwise this
-   * method will throw a {@link ClassCastException}.
-   */
-  public static <T> void setDelegate(Provider<T> delegateFactory, Provider<T> delegate) {
-    checkNotNull(delegate);
-    DelegateFactory<T> asDelegateFactory = (DelegateFactory<T>) delegateFactory;
-    if (asDelegateFactory.delegate != null) {
-      throw new IllegalStateException();
-    }
-    asDelegateFactory.delegate = delegate;
-  }
-
-  /**
-   * Returns the factory's delegate.
-   *
-   * @throws NullPointerException if the delegate has not been set
-   */
-  Provider<T> getDelegate() {
-    return checkNotNull(delegate);
-  }
-}
-
diff --git a/java/dagger/internal/DoubleCheck.java b/java/dagger/internal/DoubleCheck.java
deleted file mode 100644
index ea07528..0000000
--- a/java/dagger/internal/DoubleCheck.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import dagger.Lazy;
-import javax.inject.Provider;
-
-/**
- * A {@link Lazy} and {@link Provider} implementation that memoizes the value returned from a
- * delegate using the double-check idiom described in Item 71 of <i>Effective Java 2</i>.
- */
-public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
-  private static final Object UNINITIALIZED = new Object();
-
-  private volatile Provider<T> provider;
-  private volatile Object instance = UNINITIALIZED;
-
-  private DoubleCheck(Provider<T> provider) {
-    assert provider != null;
-    this.provider = provider;
-  }
-
-  @SuppressWarnings("unchecked") // cast only happens when result comes from the provider
-  @Override
-  public T get() {
-    Object result = instance;
-    if (result == UNINITIALIZED) {
-      synchronized (this) {
-        result = instance;
-        if (result == UNINITIALIZED) {
-          result = provider.get();
-          instance = reentrantCheck(instance, result);
-          /* Null out the reference to the provider. We are never going to need it again, so we
-           * can make it eligible for GC. */
-          provider = null;
-        }
-      }
-    }
-    return (T) result;
-  }
-
-  /**
-   * Checks to see if creating the new instance has resulted in a recursive call. If it has, and the
-   * new instance is the same as the current instance, return the instance. However, if the new
-   * instance differs from the current instance, an {@link IllegalStateException} is thrown.
-   */
-  public static Object reentrantCheck(Object currentInstance, Object newInstance) {
-    boolean isReentrant = !(currentInstance == UNINITIALIZED
-        // This check is needed for fastInit's implementation, which uses MemoizedSentinel types.
-        || currentInstance instanceof MemoizedSentinel);
-
-    if (isReentrant && currentInstance != newInstance) {
-      throw new IllegalStateException("Scoped provider was invoked recursively returning "
-          + "different results: " + currentInstance + " & " + newInstance + ". This is likely "
-          + "due to a circular dependency.");
-    }
-    return newInstance;
-  }
-
-  /** Returns a {@link Provider} that caches the value from the given delegate provider. */
-  // This method is declared this way instead of "<T> Provider<T> provider(Provider<T> delegate)"
-  // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949.
-  public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
-    checkNotNull(delegate);
-    if (delegate instanceof DoubleCheck) {
-      /* This should be a rare case, but if we have a scoped @Binds that delegates to a scoped
-       * binding, we shouldn't cache the value again. */
-      return delegate;
-    }
-    return new DoubleCheck<T>(delegate);
-  }
-
-  /** Returns a {@link Lazy} that caches the value from the given provider. */
-  // This method is declared this way instead of "<T> Lazy<T> lazy(Provider<T> delegate)"
-  // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949.
-  public static <P extends Provider<T>, T> Lazy<T> lazy(P provider) {
-    if (provider instanceof Lazy) {
-      @SuppressWarnings("unchecked")
-      final Lazy<T> lazy = (Lazy<T>) provider;
-      // Avoids memoizing a value that is already memoized.
-      // NOTE: There is a pathological case where Provider<P> may implement Lazy<L>, but P and L
-      // are different types using covariant return on get(). Right now this is used with
-      // DoubleCheck<T> exclusively, which is implemented such that P and L are always
-      // the same, so it will be fine for that case.
-      return lazy;
-    }
-    return new DoubleCheck<T>(checkNotNull(provider));
-  }
-}
diff --git a/java/dagger/internal/Factory.java b/java/dagger/internal/Factory.java
deleted file mode 100644
index 9c03f81..0000000
--- a/java/dagger/internal/Factory.java
+++ /dev/null
@@ -1,36 +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;
-
-import dagger.Provides;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Scope;
-
-/**
- * An {@linkplain Scope unscoped} {@link Provider}. While a {@link Provider} <i>may</i> apply
- * scoping semantics while providing an instance, a factory implementation is guaranteed to exercise
- * the binding logic ({@link Inject} constructors, {@link Provides} methods) upon each call to
- * {@link #get}.
- *
- * <p>Note that while subsequent calls to {@link #get} will create new instances for bindings such
- * as those created by {@link Inject} constructors, a new instance is not guaranteed by all
- * bindings. For example, {@link Provides} methods may be implemented in ways that return the same
- * instance for each call.
- */
-public interface Factory<T> extends Provider<T> {
-}
diff --git a/java/dagger/internal/GenerationOptions.java b/java/dagger/internal/GenerationOptions.java
deleted file mode 100644
index 996cd1d..0000000
--- a/java/dagger/internal/GenerationOptions.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-/**
- * Metadata annotation for base subcomponent implementations in ahead-of-time compilations. This
- * propagates any compiler options related to code generation so that later compilations can
- * recreate the model of the generated code of superclass implementations.
- */
-@Target(ElementType.TYPE)
-public @interface GenerationOptions {
-  boolean fastInit();
-}
diff --git a/java/dagger/internal/GwtIncompatible.java b/java/dagger/internal/GwtIncompatible.java
deleted file mode 100644
index f6100a2..0000000
--- a/java/dagger/internal/GwtIncompatible.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-/** Marks an element incompatible with GWT. */
-public @interface GwtIncompatible {}
diff --git a/java/dagger/internal/InstanceFactory.java b/java/dagger/internal/InstanceFactory.java
deleted file mode 100644
index 3156fe8..0000000
--- a/java/dagger/internal/InstanceFactory.java
+++ /dev/null
@@ -1,61 +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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import dagger.Lazy;
-
-/**
- * A {@link Factory} implementation that returns a single instance for all invocations of {@link
- * #get}.
- *
- * <p>Note that while this is a {@link Factory} implementation, and thus unscoped, each call to
- * {@link #get} will always return the same instance. As such, any scoping applied to this factory
- * is redundant and unnecessary. However, using this with {@link DoubleCheck#provider} is valid and
- * may be desired for testing or contractual guarantees.
- */
-public final class InstanceFactory<T> implements Factory<T>, Lazy<T> {
-  public static <T> Factory<T> create(T instance) {
-    return new InstanceFactory<T>(checkNotNull(instance, "instance cannot be null"));
-  }
-
-  public static <T> Factory<T> createNullable(T instance) {
-    return instance == null
-        ? InstanceFactory.<T>nullInstanceFactory()
-        : new InstanceFactory<T>(instance);
-  }
-
-  @SuppressWarnings("unchecked") // bivariant implementation
-  private static <T> InstanceFactory<T> nullInstanceFactory() {
-    return (InstanceFactory<T>) NULL_INSTANCE_FACTORY;
-  }
-
-  private static final InstanceFactory<Object> NULL_INSTANCE_FACTORY =
-      new InstanceFactory<Object>(null);
-
-  private final T instance;
-
-  private InstanceFactory(T instance) {
-    this.instance = instance;
-  }
-
-  @Override
-  public T get() {
-    return instance;
-  }
-}
diff --git a/java/dagger/internal/MapBuilder.java b/java/dagger/internal/MapBuilder.java
deleted file mode 100644
index 25e2b5b..0000000
--- a/java/dagger/internal/MapBuilder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * A fluent builder class that returns a {@link Map}. Used in component implementations where a map
- * must be created in one fluent statement for inlined request fulfillments.
- */
-public final class MapBuilder<K, V> {
-  private final Map<K, V> contributions;
-
-  private MapBuilder(int size) {
-    contributions = newLinkedHashMapWithExpectedSize(size);
-  }
-
-  /**
-   * Creates a new {@link MapBuilder} with {@code size} elements.
-   */
-  public static <K, V> MapBuilder<K, V> newMapBuilder(int size) {
-    return new MapBuilder<>(size);
-  }
-
-  public MapBuilder<K, V> put(K key, V value) {
-    contributions.put(key, value);
-    return this;
-  }
-
-  public MapBuilder<K, V> putAll(Map<K, V> map) {
-    contributions.putAll(map);
-    return this;
-  }
-
-  public Map<K, V> build() {
-    switch (contributions.size()) {
-      case 0:
-        return Collections.emptyMap();
-      default:
-        return Collections.unmodifiableMap(contributions);
-    }
-  }
-}
diff --git a/java/dagger/internal/MapFactory.java b/java/dagger/internal/MapFactory.java
deleted file mode 100644
index 8eb0783..0000000
--- a/java/dagger/internal/MapFactory.java
+++ /dev/null
@@ -1,84 +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;
-
-import static dagger.internal.DaggerCollections.newLinkedHashMapWithExpectedSize;
-import static java.util.Collections.unmodifiableMap;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.inject.Provider;
-
-/**
- * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a
- * {@code Map<K, V>} when calling {@link #get} (as specified by {@link Factory}).
- */
-public final class MapFactory<K, V> extends AbstractMapFactory<K, V, V> {
-  private static final Provider<Map<Object, Object>> EMPTY =
-      InstanceFactory.create(Collections.emptyMap());
-
-  /** Returns a new {@link Builder} */
-  public static <K, V> Builder<K, V> builder(int size) {
-    return new Builder<>(size);
-  }
-
-  /** Returns a factory of an empty map. */
-  @SuppressWarnings("unchecked") // safe contravariant cast
-  public static <K, V> Provider<Map<K, V>> emptyMapProvider() {
-    return (Provider<Map<K, V>>) (Provider) EMPTY;
-  }
-
-  private MapFactory(Map<K, Provider<V>> map) {
-    super(map);
-  }
-
-  /**
-   * Returns a {@code Map<K, V>} whose iteration order is that of the elements given by each of the
-   * providers, which are invoked in the order given at creation.
-   */
-  @Override
-  public Map<K, V> get() {
-    Map<K, V> result = newLinkedHashMapWithExpectedSize(contributingMap().size());
-    for (Entry<K, Provider<V>> entry : contributingMap().entrySet()) {
-      result.put(entry.getKey(), entry.getValue().get());
-    }
-    return unmodifiableMap(result);
-  }
-
-  /** A builder for {@link MapFactory}. */
-  public static final class Builder<K, V> extends AbstractMapFactory.Builder<K, V, V> {
-    private Builder(int size) {
-      super(size);
-    }
-
-    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
-      super.put(key, providerOfValue);
-      return this;
-    }
-
-    public Builder<K, V> putAll(Provider<Map<K, V>> mapFactory) {
-      super.putAll(mapFactory);
-      return this;
-    }
-
-    /** Returns a new {@link MapProviderFactory}. */
-    public MapFactory<K, V> build() {
-      return new MapFactory<>(map);
-    }
-  }
-}
diff --git a/java/dagger/internal/MapProviderFactory.java b/java/dagger/internal/MapProviderFactory.java
deleted file mode 100644
index 1fe4788..0000000
--- a/java/dagger/internal/MapProviderFactory.java
+++ /dev/null
@@ -1,71 +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;
-
-import dagger.Lazy;
-import java.util.Map;
-import javax.inject.Provider;
-
-/**
- * A {@link Factory} implementation used to implement {@link Map} bindings. This factory returns a
- * {@code Map<K, Provider<V>>} when calling {@link #get} (as specified by {@link Factory}).
- */
-public final class MapProviderFactory<K, V> extends AbstractMapFactory<K, V, Provider<V>>
-    implements Lazy<Map<K, Provider<V>>> {
-
-  /** Returns a new {@link Builder} */
-  public static <K, V> Builder<K, V> builder(int size) {
-    return new Builder<>(size);
-  }
-
-  private MapProviderFactory(Map<K, Provider<V>> contributingMap) {
-    super(contributingMap);
-  }
-
-  /**
-   * Returns a {@code Map<K, Provider<V>>} whose iteration order is that of the elements given by
-   * each of the providers, which are invoked in the order given at creation.
-   */
-  @Override
-  public Map<K, Provider<V>> get() {
-    return contributingMap();
-  }
-
-  /** A builder for {@link MapProviderFactory}. */
-  public static final class Builder<K, V> extends AbstractMapFactory.Builder<K, V, Provider<V>> {
-    private Builder(int size) {
-      super(size);
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
-      super.put(key, providerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> putAll(Provider<Map<K, Provider<V>>> mapProviderFactory) {
-      super.putAll(mapProviderFactory);
-      return this;
-    }
-
-    /** Returns a new {@link MapProviderFactory}. */
-    public MapProviderFactory<K, V> build() {
-      return new MapProviderFactory<>(map);
-    }
-  }
-}
diff --git a/java/dagger/internal/MembersInjectors.java b/java/dagger/internal/MembersInjectors.java
deleted file mode 100644
index aae068c..0000000
--- a/java/dagger/internal/MembersInjectors.java
+++ /dev/null
@@ -1,48 +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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import dagger.MembersInjector;
-import javax.inject.Inject;
-
-/**
- * Basic {@link MembersInjector} implementations used by the framework.
- */
-public final class MembersInjectors {
-  /**
-   * Returns a {@link MembersInjector} implementation that injects no members
-   *
-   * <p>Note that there is no verification that the type being injected does not have {@link Inject}
-   * members, so care should be taken to ensure appropriate use.
-   */
-  @SuppressWarnings("unchecked")
-  public static <T> MembersInjector<T> noOp() {
-    return (MembersInjector<T>) NoOpMembersInjector.INSTANCE;
-  }
-
-  private static enum NoOpMembersInjector implements MembersInjector<Object> {
-    INSTANCE;
-
-    @Override public void injectMembers(Object instance) {
-      checkNotNull(instance, "Cannot inject members into a null reference");
-    }
-  }
-
-  private MembersInjectors() {}
-}
diff --git a/java/dagger/internal/MemoizedSentinel.java b/java/dagger/internal/MemoizedSentinel.java
deleted file mode 100644
index dd24dcd..0000000
--- a/java/dagger/internal/MemoizedSentinel.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-/** A sentinel used to memoize a scoped binding in a component. */
-public final class MemoizedSentinel {}
diff --git a/java/dagger/internal/MissingBindingFactory.java b/java/dagger/internal/MissingBindingFactory.java
deleted file mode 100644
index 993d150..0000000
--- a/java/dagger/internal/MissingBindingFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-/**
- * A {@link Factory} that always throws on calls to {@link Factory#get()}. This is necessary in
- * ahead-of-time subcomponents mode, where modifiable binding methods need to return a {@code
- * Provider<T>} to a framework instance initialization that is pruned and no longer in the binding
- * graph, but was present in a superclass implementation. This class fulfills that requirement but
- * is still practically unusable.
- */
-public final class MissingBindingFactory<T> implements Factory<T> {
-  private static final MissingBindingFactory<Object> INSTANCE = new MissingBindingFactory<>();
-
-  private MissingBindingFactory() {}
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // safe covariant cast
-  public static <T> Factory<T> create() {
-    return (Factory) INSTANCE;
-  }
-
-  @Override
-  public T get() {
-    throw new AssertionError(
-        "This binding is not part of the final binding graph. The key was requested by a binding "
-            + "that was believed to possibly be part of the graph, but is no longer requested. "
-            + "If this exception is thrown, it is the result of a Dagger bug.");
-  }
-}
diff --git a/java/dagger/internal/ModifiableBinding.java b/java/dagger/internal/ModifiableBinding.java
deleted file mode 100644
index 1e658e4..0000000
--- a/java/dagger/internal/ModifiableBinding.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static java.lang.annotation.ElementType.METHOD;
-
-import java.lang.annotation.Target;
-
-/** Annotates methods that implement bindings that may be modified by subclass implementations. */
-@Target(METHOD)
-public @interface ModifiableBinding {
-  /** {@code ModifiableBindingType} of the binding. */
-  // TODO(ronshapiro): should this be a shared enum with dagger.internal.codegen?
-  String modifiableBindingType();
-
-  /** A {@link dagger.internal.codegen.serialization.BindingRequestProto} serialized in Base64. */
-  String bindingRequest();
-
-  /**
-   * For a multibinding, the keys of all contributions it depends on in this implementation.
-   */
-  String[] multibindingContributions() default {};
-}
diff --git a/java/dagger/internal/ModifiableModule.java b/java/dagger/internal/ModifiableModule.java
deleted file mode 100644
index 983321e..0000000
--- a/java/dagger/internal/ModifiableModule.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-/**
- * Annotates methods that return {@linkplain dagger.Module modules} that may be modified by subclass
- * implementations.
- */
-public @interface ModifiableModule {
-  /** The serialized {@code ComponentRequirement} of this method's module. */
-  String value();
-}
diff --git a/java/dagger/internal/Preconditions.java b/java/dagger/internal/Preconditions.java
deleted file mode 100644
index 714a353..0000000
--- a/java/dagger/internal/Preconditions.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-/**
- * An adaptation of Guava's {@code com.google.common.base.Preconditions} that is specially tailored
- * to support checks applied in Dagger's generated code.
- */
-public final class Preconditions {
-  /**
-   * Ensures that an object reference passed as a parameter to the calling method is not null.
-   *
-   * @param reference an object reference
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   */
-  public static <T> T checkNotNull(T reference) {
-    if (reference == null) {
-      throw new NullPointerException();
-    }
-    return reference;
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling method is not null.
-   *
-   * @param reference an object reference
-   * @param errorMessage the exception message to use if the check fails
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   */
-  public static <T> T checkNotNull(T reference, String errorMessage) {
-    if (reference == null) {
-      throw new NullPointerException(errorMessage);
-    }
-    return reference;
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling method is not null.
-   *
-   * @param reference an object reference
-   * @param errorMessageTemplate a template for the exception message should the check fail. The
-   *     message is formed by replacing the single {@code %s} placeholder in the template with
-   *     {@code errorMessageArg}.
-   * @param errorMessageArg the argument to be substituted into the message template. Converted to a
-   *     string using {@link String#valueOf(Object)}, except for {@link Class} objects, which use
-   *     {@link Class#getCanonicalName()}.
-   * @return the non-null reference that was validated
-   * @throws NullPointerException if {@code reference} is null
-   * @throws IllegalArgumentException if {@code errorMessageTemplate} doesn't contain exactly one
-   *     "%s"
-   */
-  public static <T> T checkNotNull(
-      T reference, String errorMessageTemplate, Object errorMessageArg) {
-    if (reference == null) {
-      // Simple implementation of String.format, which is not GWT-compatible
-      if (!errorMessageTemplate.contains("%s")) {
-        throw new IllegalArgumentException("errorMessageTemplate has no format specifiers");
-      }
-      if (errorMessageTemplate.indexOf("%s") != errorMessageTemplate.lastIndexOf("%s")) {
-        throw new IllegalArgumentException(
-            "errorMessageTemplate has more than one format specifier");
-      }
-      String argString =
-          errorMessageArg instanceof Class
-              ? ((Class) errorMessageArg).getCanonicalName()
-              : String.valueOf(errorMessageArg);
-      throw new NullPointerException(errorMessageTemplate.replace("%s", argString));
-    }
-    return reference;
-  }
-
-  /**
-   * Checks that the component builder field {@code requirement} has been initialized.
-   *
-   * @throws IllegalStateException if {@code requirement is null}
-   */
-  public static <T> void checkBuilderRequirement(T requirement, Class<T> clazz) {
-    if (requirement == null) {
-      throw new IllegalStateException(clazz.getCanonicalName() + " must be set");
-    }
-  }
-
-  private Preconditions() {}
-}
diff --git a/java/dagger/internal/ProviderOfLazy.java b/java/dagger/internal/ProviderOfLazy.java
deleted file mode 100644
index 23b6afd..0000000
--- a/java/dagger/internal/ProviderOfLazy.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import dagger.Lazy;
-import javax.inject.Provider;
-
-/**
- * A {@link Provider} of {@link Lazy} instances that each delegate to a given {@link Provider}.
- */
-public final class ProviderOfLazy<T> implements Provider<Lazy<T>> {
-
-  private final Provider<T> provider;
-
-  private ProviderOfLazy(Provider<T> provider) {
-    assert provider != null;
-    this.provider = provider;
-  }
-
-  /**
-   * Returns a new instance of {@link Lazy Lazy&lt;T&gt;}, which calls {@link Provider#get()} at
-   * most once on the {@link Provider} held by this object.
-   */
-  @Override
-  public Lazy<T> get() {
-    return DoubleCheck.lazy(provider);
-  }
-
-  /**
-   * Creates a new {@link Provider Provider&lt;Lazy&lt;T&gt;&gt;} that decorates the given
-   * {@link Provider}.
-   *
-   * @see #get()
-   */
-  public static <T> Provider<Lazy<T>> create(Provider<T> provider) {
-    return new ProviderOfLazy<T>(checkNotNull(provider));
-  }
-}
diff --git a/java/dagger/internal/SetBuilder.java b/java/dagger/internal/SetBuilder.java
deleted file mode 100644
index 41a2fc7..0000000
--- a/java/dagger/internal/SetBuilder.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A fluent builder class that returns a {@link Set}. Used in component implementations where a set
- * must be created in one fluent statement for inlined request fulfillments.
- */
-public final class SetBuilder<T> {
-  private static final String SET_CONTRIBUTIONS_CANNOT_BE_NULL =
-      "Set contributions cannot be null";
-  private final List<T> contributions;
-
-  private SetBuilder(int estimatedSize) {
-    contributions = new ArrayList<>(estimatedSize);
-  }
-
-  /**
-   * {@code estimatedSize} is the number of bindings which contribute to the set. They may each
-   * provide {@code [0..n)} instances to the set. Because the final size is unknown, {@code
-   * contributions} are collected in a list and only hashed in {@link #build()}.
-   */
-  public static <T> SetBuilder<T> newSetBuilder(int estimatedSize) {
-    return new SetBuilder<T>(estimatedSize);
-  }
-
-  public SetBuilder<T> add(T t) {
-    contributions.add(checkNotNull(t, SET_CONTRIBUTIONS_CANNOT_BE_NULL));
-    return this;
-  }
-
-  public SetBuilder<T> addAll(Collection<? extends T> collection) {
-    for (T item : collection) {
-      checkNotNull(item, SET_CONTRIBUTIONS_CANNOT_BE_NULL);
-    }
-    contributions.addAll(collection);
-    return this;
-  }
-
-  public Set<T> build() {
-    switch (contributions.size()) {
-      case 0:
-        return Collections.emptySet();
-      case 1:
-        return Collections.singleton(contributions.get(0));
-      default:
-        return Collections.unmodifiableSet(new HashSet<>(contributions));
-    }
-  }
-}
diff --git a/java/dagger/internal/SetFactory.java b/java/dagger/internal/SetFactory.java
deleted file mode 100644
index 349399b..0000000
--- a/java/dagger/internal/SetFactory.java
+++ /dev/null
@@ -1,136 +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;
-
-import static dagger.internal.DaggerCollections.hasDuplicates;
-import static dagger.internal.DaggerCollections.newHashSetWithExpectedSize;
-import static dagger.internal.DaggerCollections.presizedList;
-import static dagger.internal.Preconditions.checkNotNull;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.unmodifiableSet;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import javax.inject.Provider;
-
-/**
- * A {@link Factory} implementation used to implement {@link Set} bindings. This factory always
- * returns a new {@link Set} instance for each call to {@link #get} (as required by {@link Factory})
- * whose elements are populated by subsequent calls to their {@link Provider#get} methods.
- */
-public final class SetFactory<T> implements Factory<Set<T>> {
-  private static final Factory<Set<Object>> EMPTY_FACTORY = InstanceFactory.create(emptySet());
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // safe covariant cast
-  public static <T> Factory<Set<T>> empty() {
-    return (Factory) EMPTY_FACTORY;
-  }
-
-  /**
-   * Constructs a new {@link Builder} for a {@link SetFactory} with {@code individualProviderSize}
-   * individual {@code Provider<T>} and {@code collectionProviderSize} {@code
-   * Provider<Collection<T>>} instances.
-   */
-  public static <T> Builder<T> builder(int individualProviderSize, int collectionProviderSize) {
-    return new Builder<T>(individualProviderSize, collectionProviderSize);
-  }
-
-  /**
-   * A builder to accumulate {@code Provider<T>} and {@code Provider<Collection<T>>} instances.
-   * These are only intended to be single-use and from within generated code. Do <em>NOT</em> add
-   * providers after calling {@link #build()}.
-   */
-  public static final class Builder<T> {
-    private final List<Provider<T>> individualProviders;
-    private final List<Provider<Collection<T>>> collectionProviders;
-
-    private Builder(int individualProviderSize, int collectionProviderSize) {
-      individualProviders = presizedList(individualProviderSize);
-      collectionProviders = presizedList(collectionProviderSize);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addProvider(Provider<? extends T> individualProvider) {
-      assert individualProvider != null : "Codegen error? Null provider";
-      // TODO(ronshapiro): Store a List<? extends Provider<T>> and avoid the cast to Provider<T>
-      individualProviders.add((Provider<T>) individualProvider);
-      return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addCollectionProvider(
-        Provider<? extends Collection<? extends T>> collectionProvider) {
-      assert collectionProvider != null : "Codegen error? Null provider";
-      collectionProviders.add((Provider<Collection<T>>) collectionProvider);
-      return this;
-    }
-
-    public SetFactory<T> build() {
-      assert !hasDuplicates(individualProviders)
-          : "Codegen error?  Duplicates in the provider list";
-      assert !hasDuplicates(collectionProviders)
-          : "Codegen error?  Duplicates in the provider list";
-
-      return new SetFactory<T>(individualProviders, collectionProviders);
-    }
-  }
-
-  private final List<Provider<T>> individualProviders;
-  private final List<Provider<Collection<T>>> collectionProviders;
-
-  private SetFactory(
-      List<Provider<T>> individualProviders, List<Provider<Collection<T>>> collectionProviders) {
-    this.individualProviders = individualProviders;
-    this.collectionProviders = collectionProviders;
-  }
-
-  /**
-   * Returns a {@link Set} that contains the elements given by each of the providers.
-   *
-   * @throws NullPointerException if any of the delegate {@link Set} instances or elements therein
-   *     are {@code null}
-   */
-  @Override
-  public Set<T> get() {
-    int size = individualProviders.size();
-    // Profiling revealed that this method was a CPU-consuming hotspot in some applications, so
-    // these loops were changed to use c-style for.  Versus enhanced for-each loops, C-style for is
-    // faster for ArrayLists, at least through Java 8.
-
-    List<Collection<T>> providedCollections =
-        new ArrayList<Collection<T>>(collectionProviders.size());
-    for (int i = 0, c = collectionProviders.size(); i < c; i++) {
-      Collection<T> providedCollection = collectionProviders.get(i).get();
-      size += providedCollection.size();
-      providedCollections.add(providedCollection);
-    }
-
-    Set<T> providedValues = newHashSetWithExpectedSize(size);
-    for (int i = 0, c = individualProviders.size(); i < c; i++) {
-      providedValues.add(checkNotNull(individualProviders.get(i).get()));
-    }
-    for (int i = 0, c = providedCollections.size(); i < c; i++) {
-      for (T element : providedCollections.get(i)) {
-        providedValues.add(checkNotNull(element));
-      }
-    }
-
-    return unmodifiableSet(providedValues);
-  }
-}
diff --git a/java/dagger/internal/SingleCheck.java b/java/dagger/internal/SingleCheck.java
deleted file mode 100644
index 4128069..0000000
--- a/java/dagger/internal/SingleCheck.java
+++ /dev/null
@@ -1,70 +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;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import javax.inject.Provider;
-
-/**
- * A {@link Provider} implementation that memoizes the result of another {@link Provider} using
- * simple lazy initialization, not the double-checked lock pattern.
- */
-public final class SingleCheck<T> implements Provider<T> {
-  private static final Object UNINITIALIZED = new Object();
-
-  private volatile Provider<T> provider;
-  private volatile Object instance = UNINITIALIZED;
-
-  private SingleCheck(Provider<T> provider) {
-    assert provider != null;
-    this.provider = provider;
-  }
-
-  @SuppressWarnings("unchecked") // cast only happens when result comes from the delegate provider
-  @Override
-  public T get() {
-    Object local = instance;
-    if (local == UNINITIALIZED) {
-      // provider is volatile and might become null after the check, so retrieve the provider first
-      Provider<T> providerReference = provider;
-      if (providerReference == null) {
-        // The provider was null, so the instance must already be set
-        local = instance;
-      } else {
-        local = providerReference.get();
-        instance = local;
-
-        // Null out the reference to the provider. We are never going to need it again, so we can
-        // make it eligible for GC.
-        provider = null;
-      }
-    }
-    return (T) local;
-  }
-
-  /** Returns a {@link Provider} that caches the value from the given delegate provider. */
-  // This method is declared this way instead of "<T> Provider<T> provider(Provider<T> provider)" 
-  // to work around an Eclipse type inference bug: https://github.com/google/dagger/issues/949.
-  public static <P extends Provider<T>, T> Provider<T> provider(P provider) {
-    // If a scoped @Binds delegates to a scoped binding, don't cache the value again.
-    if (provider instanceof SingleCheck || provider instanceof DoubleCheck) {
-      return provider;
-    }
-    return new SingleCheck<T>(checkNotNull(provider));
-  }
-}
diff --git a/java/dagger/internal/codegen/AnnotationCreatorGenerator.java b/java/dagger/internal/codegen/AnnotationCreatorGenerator.java
deleted file mode 100644
index 273f552..0000000
--- a/java/dagger/internal/codegen/AnnotationCreatorGenerator.java
+++ /dev/null
@@ -1,167 +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.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.javapoet.CodeBlocks.makeParametersCodeBlock;
-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;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.LinkedHashSet;
-import java.util.Optional;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-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.type.DeclaredType;
-import javax.lang.model.util.SimpleTypeVisitor6;
-
-/**
- * Generates classes that create annotation instances for an annotation type. The generated class
- * will have a private empty constructor, a static method that creates the annotation type itself,
- * and a static method that creates each annotation type that is nested in the top-level annotation
- * type.
- *
- * <p>So for an example annotation:
- *
- * <pre>
- *   {@literal @interface} Foo {
- *     String s();
- *     int i();
- *     Bar bar(); // an annotation defined elsewhere
- *   }
- * </pre>
- *
- * the generated class will look like:
- *
- * <pre>
- *   public final class FooCreator {
- *     private FooCreator() {}
- *
- *     public static Foo createFoo(String s, int i, Bar bar) { … }
- *     public static Bar createBar(…) { … }
- *   }
- * </pre>
- */
-class AnnotationCreatorGenerator extends SourceFileGenerator<TypeElement> {
-  private static final ClassName AUTO_ANNOTATION =
-      ClassName.get("com.google.auto.value", "AutoAnnotation");
-
-  @Inject
-  AnnotationCreatorGenerator(Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-  }
-
-  @Override
-  ClassName nameGeneratedType(TypeElement annotationType) {
-    return getAnnotationCreatorClassName(annotationType);
-  }
-
-  @Override
-  Element originatingElement(TypeElement annotationType) {
-    return annotationType;
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, TypeElement annotationType) {
-    TypeSpec.Builder annotationCreatorBuilder =
-        classBuilder(generatedTypeName)
-            .addModifiers(PUBLIC, FINAL)
-            .addMethod(constructorBuilder().addModifiers(PRIVATE).build());
-
-    for (TypeElement annotationElement : annotationsToCreate(annotationType)) {
-      annotationCreatorBuilder.addMethod(buildCreateMethod(generatedTypeName, annotationElement));
-    }
-
-    return Optional.of(annotationCreatorBuilder);
-  }
-
-  private MethodSpec buildCreateMethod(ClassName generatedTypeName, TypeElement annotationElement) {
-    String createMethodName = createMethodName(annotationElement);
-    MethodSpec.Builder createMethod =
-        methodBuilder(createMethodName)
-            .addAnnotation(AUTO_ANNOTATION)
-            .addModifiers(PUBLIC, STATIC)
-            .returns(TypeName.get(annotationElement.asType()));
-
-    ImmutableList.Builder<CodeBlock> parameters = ImmutableList.builder();
-    for (ExecutableElement annotationMember : methodsIn(annotationElement.getEnclosedElements())) {
-      String parameterName = annotationMember.getSimpleName().toString();
-      TypeName parameterType = TypeName.get(annotationMember.getReturnType());
-      createMethod.addParameter(parameterType, parameterName);
-      parameters.add(CodeBlock.of("$L", parameterName));
-    }
-
-    ClassName autoAnnotationClass =
-        generatedTypeName.peerClass(
-            "AutoAnnotation_" + generatedTypeName.simpleName() + "_" + createMethodName);
-    createMethod.addStatement(
-        "return new $T($L)", autoAnnotationClass, makeParametersCodeBlock(parameters.build()));
-    return createMethod.build();
-  }
-
-  /**
-   * Returns the annotation types for which {@code @AutoAnnotation static Foo createFoo(…)} methods
-   * should be written.
-   */
-  protected Set<TypeElement> annotationsToCreate(TypeElement annotationElement) {
-    return nestedAnnotationElements(annotationElement, new LinkedHashSet<>());
-  }
-
-  @CanIgnoreReturnValue
-  private static Set<TypeElement> nestedAnnotationElements(
-      TypeElement annotationElement, Set<TypeElement> annotationElements) {
-    if (annotationElements.add(annotationElement)) {
-      for (ExecutableElement method : methodsIn(annotationElement.getEnclosedElements())) {
-        TRAVERSE_NESTED_ANNOTATIONS.visit(method.getReturnType(), annotationElements);
-      }
-    }
-    return annotationElements;
-  }
-
-  private static final SimpleTypeVisitor6<Void, Set<TypeElement>> TRAVERSE_NESTED_ANNOTATIONS =
-      new SimpleTypeVisitor6<Void, Set<TypeElement>>() {
-        @Override
-        public Void visitDeclared(DeclaredType t, Set<TypeElement> p) {
-          TypeElement typeElement = MoreTypes.asTypeElement(t);
-          if (typeElement.getKind() == ElementKind.ANNOTATION_TYPE) {
-            nestedAnnotationElements(typeElement, p);
-          }
-          return null;
-        }
-      };
-}
diff --git a/java/dagger/internal/codegen/AnnotationExpression.java b/java/dagger/internal/codegen/AnnotationExpression.java
deleted file mode 100644
index 8d729e2..0000000
--- a/java/dagger/internal/codegen/AnnotationExpression.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
-import static dagger.internal.codegen.SourceFiles.classFileName;
-import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
-import static java.util.stream.Collectors.toList;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.TypeName;
-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;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor6;
-import javax.lang.model.util.SimpleTypeVisitor6;
-
-/**
- * Returns an expression creating an instance of the visited annotation type. Its parameter must be
- * a class as generated by {@link AnnotationCreatorGenerator}.
- *
- * <p>Note that {@link AnnotationValue#toString()} is the source-code representation of the value
- * <em>when used in an annotation</em>, which is not always the same as the representation needed
- * when creating the value in a method body.
- *
- * <p>For example, inside an annotation, a nested array of {@code int}s is simply {@code {1, 2, 3}},
- * but in code it would have to be {@code new int[] {1, 2, 3}}.
- */
-class AnnotationExpression extends SimpleAnnotationValueVisitor6<CodeBlock, AnnotationValue> {
-
-  private final AnnotationMirror annotation;
-  private final ClassName creatorClass;
-
-  AnnotationExpression(AnnotationMirror annotation) {
-    this.annotation = annotation;
-    this.creatorClass =
-        getAnnotationCreatorClassName(
-            MoreTypes.asTypeElement(annotation.getAnnotationType()));
-  }
-
-  /**
-   * Returns an expression that calls static methods on the annotation's creator class to create an
-   * annotation instance equivalent the annotation passed to the constructor.
-   */
-  CodeBlock getAnnotationInstanceExpression() {
-    return getAnnotationInstanceExpression(annotation);
-  }
-
-  private CodeBlock getAnnotationInstanceExpression(AnnotationMirror annotation) {
-    return CodeBlock.of(
-        "$T.$L($L)",
-        creatorClass,
-        createMethodName(
-            MoreElements.asType(annotation.getAnnotationType().asElement())),
-        makeParametersCodeBlock(
-            getAnnotationValuesWithDefaults(annotation)
-                .entrySet()
-                .stream()
-                .map(entry -> getValueExpression(entry.getKey().getReturnType(), entry.getValue()))
-                .collect(toList())));
-  }
-
-  /**
-   * 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}.
-   */
-  CodeBlock getValueExpression(TypeMirror valueType, AnnotationValue value) {
-    return ARRAY_LITERAL_PREFIX.visit(valueType, this.visit(value, value));
-  }
-
-  @Override
-  public CodeBlock visitEnumConstant(VariableElement c, AnnotationValue p) {
-    return CodeBlock.of("$T.$L", c.getEnclosingElement(), c.getSimpleName());
-  }
-
-  @Override
-  public CodeBlock visitAnnotation(AnnotationMirror a, AnnotationValue p) {
-    return getAnnotationInstanceExpression(a);
-  }
-
-  @Override
-  public CodeBlock visitType(TypeMirror t, AnnotationValue p) {
-    return CodeBlock.of("$T.class", t);
-  }
-
-  @Override
-  public CodeBlock visitString(String s, AnnotationValue p) {
-    return CodeBlock.of("$S", s);
-  }
-
-  @Override
-  public CodeBlock visitByte(byte b, AnnotationValue p) {
-    return CodeBlock.of("(byte) $L", b);
-  }
-
-  @Override
-  public CodeBlock visitChar(char c, AnnotationValue p) {
-    return CodeBlock.of("$L", p);
-  }
-
-  @Override
-  public CodeBlock visitDouble(double d, AnnotationValue p) {
-    return CodeBlock.of("$LD", d);
-  }
-
-  @Override
-  public CodeBlock visitFloat(float f, AnnotationValue p) {
-    return CodeBlock.of("$LF", f);
-  }
-
-  @Override
-  public CodeBlock visitLong(long i, AnnotationValue p) {
-    return CodeBlock.of("$LL", i);
-  }
-
-  @Override
-  public CodeBlock visitShort(short s, AnnotationValue p) {
-    return CodeBlock.of("(short) $L", s);
-  }
-
-  @Override
-  protected CodeBlock defaultAction(Object o, AnnotationValue p) {
-    return CodeBlock.of("$L", o);
-  }
-
-  @Override
-  public CodeBlock visitArray(List<? extends AnnotationValue> values, AnnotationValue p) {
-    ImmutableList.Builder<CodeBlock> codeBlocks = ImmutableList.builder();
-    for (AnnotationValue value : values) {
-      codeBlocks.add(this.visit(value, p));
-    }
-    return CodeBlock.of("{$L}", makeParametersCodeBlock(codeBlocks.build()));
-  }
-
-  /**
-   * If the visited type is an array, prefixes the parameter code block with {@code new T[]}, where
-   * {@code T} is the raw array component type.
-   */
-  private static final SimpleTypeVisitor6<CodeBlock, CodeBlock> ARRAY_LITERAL_PREFIX =
-      new SimpleTypeVisitor6<CodeBlock, CodeBlock>() {
-
-        @Override
-        public CodeBlock visitArray(ArrayType t, CodeBlock p) {
-          return CodeBlock.of("new $T[] $L", RAW_TYPE_NAME.visit(t.getComponentType()), p);
-        }
-
-        @Override
-        protected CodeBlock defaultAction(TypeMirror e, CodeBlock p) {
-          return p;
-        }
-      };
-
-  /**
-   * If the visited type is an array, returns the name of its raw component type; otherwise returns
-   * the name of the type itself.
-   */
-  private static final SimpleTypeVisitor6<TypeName, Void> RAW_TYPE_NAME =
-      new SimpleTypeVisitor6<TypeName, Void>() {
-        @Override
-        public TypeName visitDeclared(DeclaredType t, Void p) {
-          return ClassName.get(MoreTypes.asTypeElement(t));
-        }
-
-        @Override
-        protected TypeName defaultAction(TypeMirror e, Void p) {
-          return TypeName.get(e);
-        }
-      };
-}
diff --git a/java/dagger/internal/codegen/AnnotationProtoConverter.java b/java/dagger/internal/codegen/AnnotationProtoConverter.java
deleted file mode 100644
index 282d8ca..0000000
--- a/java/dagger/internal/codegen/AnnotationProtoConverter.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2019 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.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.Maps.transformValues;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static javax.lang.model.util.ElementFilter.fieldsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import dagger.internal.codegen.serialization.AnnotationProto;
-import dagger.internal.codegen.serialization.AnnotationValueProto;
-import java.util.Collections;
-import java.util.List;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-
-/** Converts {@link AnnotationMirror}s to {@link AnnotationProto}s and vice-versa. */
-final class AnnotationProtoConverter {
-  private final TypeProtoConverter typeProtoConverter;
-
-  @Inject
-  AnnotationProtoConverter(TypeProtoConverter typeProtoConverter) {
-    this.typeProtoConverter = typeProtoConverter;
-  }
-
-  /** Translates an {@link AnnotationMirror} to a proto representation. */
-  static AnnotationProto toProto(AnnotationMirror annotationMirror) {
-    AnnotationProto.Builder builder = AnnotationProto.newBuilder();
-    builder.setAnnotationType(TypeProtoConverter.toProto(annotationMirror.getAnnotationType()));
-    getAnnotationValuesWithDefaults(annotationMirror)
-        .forEach(
-            (attribute, value) ->
-                builder.putAllValues(
-                    Collections.singletonMap(
-                        attribute.getSimpleName().toString(), annotationValueProto(value))));
-    return builder.build();
-  }
-
-  /** Creates an {@link AnnotationMirror} from its proto representation. */
-  AnnotationMirror fromProto(AnnotationProto annotation) {
-    return SimpleAnnotationMirror.of(
-        MoreTypes.asTypeElement(typeProtoConverter.fromProto(annotation.getAnnotationType())),
-        transformValues(annotation.getValues(), AnnotationValueFromProto::new));
-  }
-
-  private static final AnnotationValueVisitor<
-          AnnotationValueProto.Builder, AnnotationValueProto.Builder>
-      ANNOTATION_VALUE_TO_PROTO =
-          new SimpleAnnotationValueVisitor8<
-              AnnotationValueProto.Builder, AnnotationValueProto.Builder>() {
-            @Override
-            public AnnotationValueProto.Builder visitAnnotation(
-                AnnotationMirror nestedAnnotation, AnnotationValueProto.Builder builder) {
-              return builder
-                  .setNestedAnnotation(toProto(nestedAnnotation))
-                  .setKind(AnnotationValueProto.Kind.ANNOTATION);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitBoolean(
-                boolean b, AnnotationValueProto.Builder builder) {
-              return builder.setBooleanValue(b).setKind(AnnotationValueProto.Kind.BOOLEAN);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitChar(
-                char c, AnnotationValueProto.Builder builder) {
-              return builder
-                  .setStringValue(String.valueOf(c))
-                  .setKind(AnnotationValueProto.Kind.CHAR);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitByte(
-                byte b, AnnotationValueProto.Builder builder) {
-              return builder.setIntValue(b).setKind(AnnotationValueProto.Kind.BYTE);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitShort(
-                short s, AnnotationValueProto.Builder builder) {
-              return builder.setIntValue(s).setKind(AnnotationValueProto.Kind.SHORT);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitInt(
-                int i, AnnotationValueProto.Builder builder) {
-              return builder.setIntValue(i).setKind(AnnotationValueProto.Kind.INT);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitFloat(
-                float f, AnnotationValueProto.Builder builder) {
-              return builder.setFloatValue(f).setKind(AnnotationValueProto.Kind.FLOAT);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitLong(
-                long l, AnnotationValueProto.Builder builder) {
-              return builder.setLongValue(l).setKind(AnnotationValueProto.Kind.LONG);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitDouble(
-                double d, AnnotationValueProto.Builder builder) {
-              return builder.setDoubleValue(d).setKind(AnnotationValueProto.Kind.DOUBLE);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitString(
-                String s, AnnotationValueProto.Builder builder) {
-              return builder.setStringValue(s).setKind(AnnotationValueProto.Kind.STRING);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitType(
-                TypeMirror t, AnnotationValueProto.Builder builder) {
-              return builder
-                  .setClassLiteral(TypeProtoConverter.toProto(t))
-                  .setKind(AnnotationValueProto.Kind.CLASS_LITERAL);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitEnumConstant(
-                VariableElement c, AnnotationValueProto.Builder builder) {
-              return builder
-                  .setEnumType(TypeProtoConverter.toProto(c.asType()))
-                  .setEnumName(c.getSimpleName().toString())
-                  .setKind(AnnotationValueProto.Kind.ENUM);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitArray(
-                List<? extends AnnotationValue> values, AnnotationValueProto.Builder builder) {
-              values.forEach(value -> builder.addArrayValues(annotationValueProto(value)));
-              return builder.setKind(AnnotationValueProto.Kind.ARRAY);
-            }
-
-            @Override
-            public AnnotationValueProto.Builder visitUnknown(
-                AnnotationValue av, AnnotationValueProto.Builder builder) {
-              throw new UnsupportedOperationException(av.toString());
-            }
-          };
-
-  /** Translates an {@link AnnotationValue} to a proto representation. */
-  private static AnnotationValueProto annotationValueProto(AnnotationValue annotationValue) {
-    return annotationValue
-        .accept(ANNOTATION_VALUE_TO_PROTO, AnnotationValueProto.newBuilder())
-        .build();
-  }
-
-  private class AnnotationValueFromProto implements AnnotationValue {
-    private final AnnotationValueProto proto;
-
-    AnnotationValueFromProto(AnnotationValueProto proto) {
-      this.proto = proto;
-    }
-
-    @Override
-    public Object getValue() {
-      switch (proto.getKind()) {
-        case BOOLEAN:
-          return proto.getBooleanValue();
-        case BYTE:
-          return (byte) proto.getIntValue();
-        case SHORT:
-          return (short) proto.getIntValue();
-        case CHAR:
-          return getCharValue();
-        case INT:
-          return proto.getIntValue();
-        case FLOAT:
-          return proto.getFloatValue();
-        case LONG:
-          return proto.getLongValue();
-        case DOUBLE:
-          return proto.getDoubleValue();
-        case STRING:
-          return proto.getStringValue();
-        case CLASS_LITERAL:
-          return typeProtoConverter.fromProto(proto.getClassLiteral());
-        case ENUM:
-          return getEnumConstant();
-        case ANNOTATION:
-          return fromProto(proto.getNestedAnnotation());
-        case ARRAY:
-          return getArrayValues();
-        case UNKNOWN:
-        case UNRECOGNIZED:
-          // fall through
-      }
-      throw new AssertionError(proto);
-    }
-
-    @Override
-    public <R, P> R accept(AnnotationValueVisitor<R, P> visitor, P passedValue) {
-      switch (proto.getKind()) {
-        case BOOLEAN:
-          return visitor.visitBoolean(proto.getBooleanValue(), passedValue);
-        case BYTE:
-          return visitor.visitByte((byte) proto.getIntValue(), passedValue);
-        case SHORT:
-          return visitor.visitShort((short) proto.getIntValue(), passedValue);
-        case CHAR:
-          return visitor.visitChar(getCharValue(), passedValue);
-        case INT:
-          return visitor.visitInt(proto.getIntValue(), passedValue);
-        case FLOAT:
-          return visitor.visitFloat(proto.getFloatValue(), passedValue);
-        case LONG:
-          return visitor.visitLong(proto.getLongValue(), passedValue);
-        case DOUBLE:
-          return visitor.visitDouble(proto.getDoubleValue(), passedValue);
-        case STRING:
-          return visitor.visitString((String) getValue(), passedValue);
-        case CLASS_LITERAL:
-          return visitor.visitType((TypeMirror) getValue(), passedValue);
-        case ENUM:
-          return visitor.visitEnumConstant((VariableElement) getValue(), passedValue);
-        case ANNOTATION:
-          return visitor.visitAnnotation((AnnotationMirror) getValue(), passedValue);
-        case ARRAY:
-          return visitor.visitArray(getArrayValues(), passedValue);
-        case UNKNOWN:
-        case UNRECOGNIZED:
-          // fall through
-      }
-      throw new AssertionError(proto);
-    }
-
-    private char getCharValue() {
-      checkState(proto.getKind().equals(AnnotationValueProto.Kind.CHAR));
-      return proto.getStringValue().charAt(0);
-    }
-
-    private VariableElement getEnumConstant() {
-      checkState(proto.getKind().equals(AnnotationValueProto.Kind.ENUM));
-      TypeMirror enumType = typeProtoConverter.fromProto(proto.getEnumType());
-      return fieldsIn(MoreTypes.asTypeElement(enumType).getEnclosedElements()).stream()
-          .filter(value -> value.getSimpleName().contentEquals(proto.getEnumName()))
-          .findFirst()
-          .get();
-    }
-
-    private ImmutableList<AnnotationValue> getArrayValues() {
-      checkState(proto.getKind().equals(AnnotationValueProto.Kind.ARRAY));
-      return proto.getArrayValuesList().stream()
-          .map(AnnotationValueFromProto::new)
-          .collect(toImmutableList());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/AnonymousProviderCreationExpression.java b/java/dagger/internal/codegen/AnonymousProviderCreationExpression.java
deleted file mode 100644
index fc30eaa..0000000
--- a/java/dagger/internal/codegen/AnonymousProviderCreationExpression.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.javapoet.CodeBlocks.anonymousProvider;
-import static dagger.model.RequestKind.INSTANCE;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.javapoet.Expression;
-
-/**
- * A {@link javax.inject.Provider} creation expression for an anonymous inner class whose
- * {@code get()} method returns the expression for an instance binding request for its key.
- */
-final class AnonymousProviderCreationExpression
-    implements FrameworkInstanceCreationExpression {
-  private final ContributionBinding binding;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final ClassName requestingClass;
-
-  AnonymousProviderCreationExpression(
-      ContributionBinding binding,
-      ComponentBindingExpressions componentBindingExpressions,
-      ClassName requestingClass) {
-    this.binding = binding;
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.requestingClass = requestingClass;
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    BindingRequest instanceExpressionRequest = bindingRequest(binding.key(), INSTANCE);
-    Expression instanceExpression =
-        componentBindingExpressions.getDependencyExpression(
-            instanceExpressionRequest,
-            // Not a real class name, but the actual requestingClass is an inner class within the
-            // given class, not that class itself.
-            requestingClass.nestedClass("Anonymous"));
-    return anonymousProvider(instanceExpression);
-  }
-}
diff --git a/java/dagger/internal/codegen/AnyBindingMethodValidator.java b/java/dagger/internal/codegen/AnyBindingMethodValidator.java
deleted file mode 100644
index bad9636..0000000
--- a/java/dagger/internal/codegen/AnyBindingMethodValidator.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-import static java.util.stream.Collectors.joining;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-
-/** Validates any binding method. */
-final class AnyBindingMethodValidator {
-
-  private final ImmutableMap<Class<? extends Annotation>, BindingMethodValidator> validators;
-  private final Map<ExecutableElement, ValidationReport<ExecutableElement>> reports =
-      new HashMap<>();
-
-  @Inject
-  AnyBindingMethodValidator(
-      ImmutableMap<Class<? extends Annotation>, BindingMethodValidator> validators) {
-    this.validators = validators;
-  }
-
-  /** Returns the binding method annotations considered by this validator. */
-  ImmutableSet<Class<? extends Annotation>> methodAnnotations() {
-    return validators.keySet();
-  }
-
-  /**
-   * Returns {@code true} if {@code method} is annotated with at least one of {@link
-   * #methodAnnotations()}.
-   */
-  boolean isBindingMethod(ExecutableElement method) {
-    return isAnyAnnotationPresent(method, methodAnnotations());
-  }
-
-  /**
-   * Returns a validation report for a method.
-   *
-   * <ul>
-   *   <li>Reports an error if {@code method} is annotated with more than one {@linkplain
-   *       #methodAnnotations() binding method annotation}.
-   *   <li>Validates {@code method} with the {@link BindingMethodValidator} for the single
-   *       {@linkplain #methodAnnotations() binding method annotation}.
-   * </ul>
-   *
-   * @throws IllegalArgumentException if {@code method} is not annotated by any {@linkplain
-   *     #methodAnnotations() binding method annotation}
-   */
-  ValidationReport<ExecutableElement> validate(ExecutableElement method) {
-    return reentrantComputeIfAbsent(reports, method, this::validateUncached);
-  }
-
-  /**
-   * Returns {@code true} if {@code method} was already {@linkplain #validate(ExecutableElement)
-   * validated}.
-   */
-  boolean wasAlreadyValidated(ExecutableElement method) {
-    return reports.containsKey(method);
-  }
-
-  private ValidationReport<ExecutableElement> validateUncached(ExecutableElement method) {
-    ValidationReport.Builder<ExecutableElement> report = ValidationReport.about(method);
-    ImmutableSet<? extends Class<? extends Annotation>> bindingMethodAnnotations =
-        methodAnnotations()
-            .stream()
-            .filter(annotation -> isAnnotationPresent(method, annotation))
-            .collect(toImmutableSet());
-    switch (bindingMethodAnnotations.size()) {
-      case 0:
-        throw new IllegalArgumentException(
-            String.format("%s has no binding method annotation", method));
-
-      case 1:
-        report.addSubreport(
-            validators.get(getOnlyElement(bindingMethodAnnotations)).validate(method));
-        break;
-
-      default:
-        report.addError(
-            String.format(
-                "%s is annotated with more than one of (%s)",
-                method.getSimpleName(),
-                methodAnnotations().stream().map(Class::getCanonicalName).collect(joining(", "))),
-            method);
-        break;
-    }
-    return report.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD
deleted file mode 100644
index 824a72e..0000000
--- a/java/dagger/internal/codegen/BUILD
+++ /dev/null
@@ -1,527 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   A JSR-330 compliant dependency injection system for android and java
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES")
-load("//tools:maven.bzl", "POM_VERSION", "pom_file")
-
-EXPERIMENTAL_VISUALIZER_SRCS = ["BindingNetworkVisualizer.java"]
-
-JAVAC_PLUGIN_MODULE_SRCS = ["JavacPluginModule.java"]
-
-KYTHE_SRCS = ["DaggerKythePlugin.java"]
-
-STATISTICS_COLLECTOR_SRCS = ["BindingGraphStatisticsCollector.java"]
-
-CODEGEN_SRCS = glob(
-    ["*.java"],
-    exclude = EXPERIMENTAL_VISUALIZER_SRCS + KYTHE_SRCS + STATISTICS_COLLECTOR_SRCS +
-              JAVAC_PLUGIN_MODULE_SRCS,
-)
-
-CODEGEN_PLUGINS = [":bootstrap_compiler_plugin"]
-
-CODEGEN_SHARED_DEPS = [
-    "@google_bazel_common//third_party/java/auto:service",
-    "@google_bazel_common//third_party/java/auto:value",
-    "@google_bazel_common//third_party/java/auto:common",
-    "@google_bazel_common//third_party/java/checker_framework_annotations",
-    "@google_bazel_common//third_party/java/error_prone:annotations",
-    "@google_bazel_common//third_party/java/google_java_format",
-    "@google_bazel_common//third_party/java/javapoet",
-    "@bazel_tools//tools/jdk:langtools-neverlink",
-    "@google_bazel_common//third_party/java/jsr250_annotations",
-    "@google_bazel_common//third_party/java/jsr330_inject",
-    "//java/dagger:core",
-    "//java/dagger/internal/codegen/serialization",
-    "//java/dagger/producers",
-    "//java/dagger/model",
-    "//java/dagger/spi",
-    "//java/dagger/model:internal-proxies",
-]
-
-CODEGEN_DEPS = CODEGEN_SHARED_DEPS + [
-    ":jdk-and-guava-extras",
-    "@google_bazel_common//third_party/java/guava",
-]
-
-# Extra features for the JDK and Guava. This code is merged into both
-# the dagger-compiler and dagger-spi artifacts that are sent to Maven
-java_library(
-    name = "jdk-and-guava-extras",
-    srcs = [
-        "DaggerGraphs.java",
-        "DaggerStreams.java",
-        "Optionals.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = [
-        "@google_bazel_common//third_party/java/guava",
-    ],
-)
-
-# Common types needed across all of the codegen package
-java_library(
-    name = "base",
-    srcs = [
-        "AnnotationProtoConverter.java",
-        "ClearableCache.java",
-        "CompilerOptions.java",
-        "ComponentAnnotation.java",
-        "ContributionType.java",
-        "DaggerStatistics.java",
-        "DaggerStatisticsCollectingProcessingStep.java",
-        "DaggerStatisticsCollector.java",
-        "DaggerStatisticsRecorder.java",
-        "DiagnosticFormatting.java",
-        "ElementFormatter.java",
-        "FeatureStatus.java",
-        "Formatter.java",
-        "ForwardingCompilerOptions.java",
-        "FrameworkTypes.java",
-        "InjectionAnnotations.java",
-        "Keys.java",
-        "MapKeyAccessibility.java",
-        "MapType.java",
-        "ModuleAnnotation.java",
-        "MoreAnnotationMirrors.java",
-        "MoreAnnotationValues.java",
-        "MultibindingAnnotations.java",
-        "OptionalType.java",
-        "ProcessingEnvironmentCompilerOptions.java",
-        "ProcessingOptions.java",
-        "RequestKinds.java",
-        "Scopes.java",
-        "SetType.java",
-        "SimpleAnnotationMirror.java",
-        "SimpleTypeAnnotationValue.java",
-        "SourceFileGenerationException.java",  # Used in :writing and :processor
-        "SourceFileGenerator.java",  # Needed by InjectBindingRegistry in :binding and also :writing
-        "TypeCheckingProcessingStep.java",
-        "TypeProtoConverter.java",
-        "UniqueNameSet.java",
-        "Util.java",
-        "ValidationType.java",
-        "package-info.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-    ],
-)
-
-# Classes that help to build a model of the binding graph
-java_library(
-    name = "binding",
-    srcs = [
-        "AnnotationExpression.java",
-        "Binding.java",
-        "BindingDeclaration.java",
-        "BindingDeclarationFormatter.java",
-        "BindingFactory.java",
-        "BindingGraph.java",
-        "BindingGraphConverter.java",
-        "BindingGraphFactory.java",
-        "BindingNode.java",
-        "BindingRequest.java",
-        "BindingType.java",
-        "BindsTypeChecker.java",
-        "ChildFactoryMethodEdgeImpl.java",
-        "ComponentCreatorAnnotation.java",
-        "ComponentCreatorDescriptor.java",
-        "ComponentCreatorKind.java",
-        "ComponentDescriptor.java",
-        "ComponentDescriptorFactory.java",
-        "ComponentKind.java",
-        "ComponentNodeImpl.java",
-        "ComponentRequirement.java",
-        "ComponentTreeTraverser.java",
-        "ConfigurationAnnotations.java",  # Uses ModuleDescriptors
-        "ContributionBinding.java",
-        "DelegateDeclaration.java",
-        "DependencyEdgeImpl.java",
-        "DependencyRequestFactory.java",
-        "DependencyRequestFormatter.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",
-        "FrameworkTypeMapper.java",
-        "InjectBindingRegistry.java",
-        "InjectionSiteFactory.java",
-        "KeyFactory.java",
-        "KeyVariableNamer.java",  # needs ConfigurationAnnotations, SourceFiles
-        "MapKeys.java",
-        "MembersInjectionBinding.java",
-        "MethodSignature.java",
-        "MethodSignatureFormatter.java",
-        "ModuleDescriptor.java",
-        "ModuleKind.java",
-        "MultibindingDeclaration.java",
-        "OptionalBindingDeclaration.java",
-        "ProductionBinding.java",
-        "ProvisionBinding.java",
-        "ResolvedBindings.java",
-        "SourceFiles.java",  # Consider splitting this up?
-        "SubcomponentCreatorBindingEdgeImpl.java",
-        "SubcomponentDeclaration.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/internal/codegen/javapoet",
-    ],
-)
-
-# Code related to validating the user-written Dagger code
-java_library(
-    name = "validation",
-    srcs = [
-        "AnyBindingMethodValidator.java",
-        "BindingElementValidator.java",
-        "BindingGraphPlugins.java",
-        "BindingGraphValidator.java",
-        "BindingMethodProcessingStep.java",
-        "BindingMethodValidator.java",
-        "BindsInstanceElementValidator.java",
-        "BindsInstanceMethodValidator.java",
-        "BindsInstanceParameterValidator.java",
-        "BindsInstanceProcessingStep.java",
-        "BindsMethodValidator.java",
-        "BindsOptionalOfMethodValidator.java",
-        "ComponentCreatorValidator.java",
-        "ComponentDescriptorValidator.java",
-        "ComponentHierarchyValidator.java",
-        "ComponentValidator.java",
-        "DependencyRequestValidator.java",
-        "DiagnosticReporterFactory.java",
-        "InjectValidator.java",
-        "MapKeyValidator.java",
-        "MembersInjectionValidator.java",
-        "ModuleValidator.java",
-        "MultibindingAnnotationsProcessingStep.java",
-        "MultibindsMethodValidator.java",
-        "ProducesMethodValidator.java",
-        "ProvidesMethodValidator.java",
-        "Validation.java",
-        "ValidationReport.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-        "//java/dagger/internal/codegen/langmodel",
-    ],
-)
-
-java_library(
-    name = "binding_graph_validation",
-    srcs = [
-        "DependencyCycleValidator.java",
-        "DependsOnProductionExecutorValidator.java",
-        "DuplicateBindingsValidator.java",
-        "IncompatiblyScopedBindingsValidator.java",
-        "InjectBindingValidator.java",
-        "MapMultibindingValidator.java",
-        "MissingBindingValidator.java",
-        "NullableBindingValidator.java",
-        "ProvisionDependencyOnProducerBindingValidator.java",
-        "SubcomponentFactoryMethodValidator.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-        ":validation",
-        "//java/dagger/internal/codegen/langmodel",
-    ],
-)
-
-# Classes that assemble the model of the generated code and write to the Filer
-java_library(
-    name = "writing",
-    srcs = [
-        "AnnotationCreatorGenerator.java",
-        "AnonymousProviderCreationExpression.java",
-        "BindingExpression.java",
-        "ComponentBindingExpressions.java",
-        "ComponentCreatorImplementation.java",
-        "ComponentImplementation.java",
-        "ComponentInstanceBindingExpression.java",
-        "ComponentMethodBindingExpression.java",
-        "ComponentProvisionBindingExpression.java",
-        "ComponentRequirementBindingExpression.java",
-        "ComponentRequirementExpression.java",
-        "ComponentRequirementExpressions.java",
-        "DeferredModifiableBindingExpression.java",
-        "DelegateBindingExpression.java",
-        "DelegatingFrameworkInstanceCreationExpression.java",
-        "DependencyMethodProducerCreationExpression.java",
-        "DependencyMethodProviderCreationExpression.java",
-        "DerivedFromFrameworkInstanceBindingExpression.java",
-        "FactoryGenerator.java",
-        "FrameworkFieldInitializer.java",
-        "FrameworkInstanceBindingExpression.java",
-        "FrameworkInstanceSupplier.java",
-        "GenerationCompilerOptions.java",
-        "GwtCompatibility.java",
-        "HjarSourceFileGenerator.java",
-        "ImmediateFutureBindingExpression.java",
-        "InaccessibleMapKeyProxyGenerator.java",
-        "InjectionMethod.java",
-        "InjectionMethods.java",
-        "InjectionOrProvisionProviderCreationExpression.java",
-        "InnerSwitchingProviders.java",
-        "InstanceFactoryCreationExpression.java",
-        "MapBindingExpression.java",
-        "MapFactoryCreationExpression.java",
-        "MemberSelect.java",
-        "MembersInjectionBindingExpression.java",
-        "MembersInjectionMethods.java",
-        "MembersInjectorGenerator.java",
-        "MembersInjectorProviderCreationExpression.java",
-        "MethodBindingExpression.java",
-        "MissingBindingExpression.java",
-        "ModifiableAbstractMethodBindingExpression.java",
-        "ModifiableBindingExpressions.java",
-        "ModifiableBindingMethods.java",
-        "ModifiableBindingType.java",
-        "ModifiableConcreteMethodBindingExpression.java",
-        "ModuleConstructorProxyGenerator.java",
-        "ModuleGenerator.java",
-        "ModuleProxies.java",
-        "MonitoringModuleGenerator.java",
-        "MonitoringModuleProcessingStep.java",
-        "MultibindingExpression.java",
-        "MultibindingFactoryCreationExpression.java",
-        "OptionalBindingExpression.java",
-        "OptionalFactories.java",
-        "OptionalFactoryInstanceCreationExpression.java",
-        "ParentComponent.java",
-        "PerComponentImplementation.java",
-        "PerGeneratedFile.java",
-        "PrivateMethodBindingExpression.java",
-        "ProducerCreationExpression.java",
-        "ProducerEntryPointView.java",
-        "ProducerFactoryGenerator.java",
-        "ProducerFromProviderCreationExpression.java",
-        "ProducerNodeInstanceBindingExpression.java",
-        "ProviderInstanceBindingExpression.java",
-        "PrunedConcreteMethodBindingExpression.java",
-        "SetBindingExpression.java",
-        "SetFactoryCreationExpression.java",
-        "SimpleInvocationBindingExpression.java",
-        "SimpleMethodBindingExpression.java",
-        "SubcomponentCreatorBindingExpression.java",
-        "SubcomponentNames.java",
-        "SwitchingProviders.java",
-        "TopLevel.java",
-        "UnwrappedMapKeyGenerator.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-    ],
-)
-
-# The processor's "main", if you will
-java_library(
-    name = "processor",
-    srcs = [
-        "BindingGraphValidationModule.java",
-        "BindingMethodValidatorsModule.java",
-        "ComponentCreatorImplementationFactory.java",
-        "ComponentGenerator.java",
-        "ComponentHjarProcessingStep.java",
-        "ComponentImplementationBuilder.java",
-        "ComponentImplementationFactory.java",
-        "ComponentProcessingStep.java",
-        "ComponentProcessor.java",
-        "CurrentImplementationSubcomponent.java",
-        "DeserializedComponentImplementationBuilder.java",
-        "GenerationOptionsModule.java",
-        "InjectBindingRegistryImpl.java",
-        "InjectBindingRegistryModule.java",
-        "InjectProcessingStep.java",
-        "MapKeyProcessingStep.java",
-        "ModuleProcessingStep.java",
-        "ProcessingEnvironmentModule.java",
-        "ProcessingRoundCacheModule.java",
-        "SourceFileGeneratorsModule.java",
-        "SpiModule.java",
-        "SystemComponentsModule.java",
-        "TopLevelImplementationComponent.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven_coordinates=com.google.dagger:dagger-compiler:" + POM_VERSION],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-        ":binding_graph_validation",
-        ":writing",
-        ":validation",
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-        "@google_bazel_common//third_party/java/incap",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-compiler",
-    artifact_name = "Dagger Compiler",
-    targets = [
-        ":processor",
-        ":base",
-        ":binding",
-        ":binding_graph_validation",
-        ":writing",
-        ":validation",
-        "//java/dagger/internal/codegen/serialization",
-        "//java/dagger/internal/codegen/javapoet",
-    ],
-)
-
-java_library(
-    name = "javac-plugin-module",
-    srcs = JAVAC_PLUGIN_MODULE_SRCS,
-    plugins = [":component-codegen"],
-    visibility = ["//visibility:private"],
-    deps = [
-        ":base",
-        ":binding",
-        ":javac",
-        ":processor",
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen/langmodel",
-    ],
-)
-
-java_library(
-    name = "kythe",
-    srcs = KYTHE_SRCS,
-    plugins = [":component-codegen"],
-    deps = [
-        ":base",
-        ":binding",
-        ":javac",
-        ":javac-plugin-module",
-        ":kythe_plugin",
-        ":processor",
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/model",
-        "//java/dagger/producers",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/guava",
-    ],
-)
-
-# Replacement for @bazel_tools//third_party/java/jdk/langtools:javac, which seems to have gone away?
-java_import(
-    name = "javac",
-    jars = ["@bazel_tools//third_party/java/jdk/langtools:javac_jar"],
-)
-
-# A _deploy.jar consisting of the java_librarys in https://github.com/kythe/kythe needed to build a
-# Kythe plugin
-# TODO(ronshapiro): replace this with a http_archive of the next release in
-# https://github.com/kythe/kythe/releases
-java_import(
-    name = "kythe_plugin",
-    jars = ["kythe_plugin_deploy.jar"],
-    neverlink = 1,
-)
-
-java_import(
-    name = "bootstrap_compiler",
-    jars = ["bootstrap_compiler_deploy.jar"],
-    visibility = ["//visibility:private"],
-)
-
-java_plugin(
-    name = "bootstrap_compiler_plugin",
-    generates_api = 1,
-    processor_class = "dagger.internal.codegen.ComponentProcessor",
-    deps = [":bootstrap_compiler"],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    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,
-    plugins = CODEGEN_PLUGINS,
-    deps = CODEGEN_DEPS + [
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/internal/codegen/javapoet",
-        "@google_bazel_common//third_party/java/incap",
-    ],
-)
-
-java_plugin(
-    name = "component-codegen",
-    generates_api = 1,
-    output_licenses = ["unencumbered"],
-    processor_class = "dagger.internal.codegen.ComponentProcessor",
-    tags = [
-        "annotation=dagger.Component;" +
-        "genclass=${package}.Dagger${outerclasses}${classname}",
-        "annotation=dagger.producers.ProductionComponent;" +
-        "genclass=${package}.Dagger${outerclasses}${classname}",
-    ],
-    deps = [":processor"],
-)
-
-java_library(
-    name = "statistics",
-    srcs = STATISTICS_COLLECTOR_SRCS,
-    plugins = [":component-codegen"],
-    deps = [
-        ":base",
-        ":binding",
-        ":javac",
-        ":javac-plugin-module",
-        ":processor",
-        "//java/dagger:core",
-        "//java/dagger/model",
-        "@google_bazel_common//third_party/java/error_prone:check_api",
-    ],
-)
diff --git a/java/dagger/internal/codegen/Binding.java b/java/dagger/internal/codegen/Binding.java
deleted file mode 100644
index c0f6b71..0000000
--- a/java/dagger/internal/codegen/Binding.java
+++ /dev/null
@@ -1,314 +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.Suppliers.memoize;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static java.util.stream.Collectors.toSet;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.Scope;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleTypeVisitor6;
-
-/**
- * An abstract type for classes representing a Dagger binding. Particularly, contains the {@link
- * Element} that generated the binding and the {@link DependencyRequest} instances that are required
- * to satisfy the binding, but leaves the specifics of the <i>mechanism</i> of the binding to the
- * subtypes.
- */
-abstract class Binding extends BindingDeclaration {
-
-  /**
-   * Returns {@code true} if using this binding requires an instance of the {@link
-   * #contributingModule()}.
-   */
-  boolean requiresModuleInstance() {
-    if (!bindingElement().isPresent() || !contributingModule().isPresent()) {
-      return false;
-    }
-    Set<Modifier> modifiers = bindingElement().get().getModifiers();
-    return !modifiers.contains(ABSTRACT) && !modifiers.contains(STATIC);
-  }
-
-  /**
-   * Returns {@code true} if this binding may provide {@code null} instead of an instance of {@link
-   * #key()}. Nullable bindings cannot be requested from {@linkplain DependencyRequest#isNullable()
-   * non-nullable dependency requests}.
-   */
-  abstract boolean isNullable();
-
-  /** The kind of binding this instance represents. */
-  abstract BindingKind kind();
-
-  /** The {@link BindingType} of this binding. */
-  abstract BindingType bindingType();
-
-  /** The {@link FrameworkType} of this binding. */
-  final FrameworkType frameworkType() {
-    return FrameworkType.forBindingType(bindingType());
-  }
-
-  /**
-   * The explicit set of {@link DependencyRequest dependencies} required to satisfy this binding as
-   * defined by the user-defined injection sites.
-   */
-  abstract ImmutableSet<DependencyRequest> explicitDependencies();
-
-  /**
-   * The set of {@link DependencyRequest dependencies} that are added by the framework rather than a
-   * user-defined injection site. This returns an unmodifiable set.
-   */
-  // TODO(gak): this will eventually get changed to return a set of FrameworkDependency
-  ImmutableSet<DependencyRequest> implicitDependencies() {
-    return ImmutableSet.of();
-  }
-
-  private final Supplier<ImmutableSet<DependencyRequest>> dependencies =
-      memoize(
-          () -> {
-            ImmutableSet<DependencyRequest> implicitDependencies = implicitDependencies();
-            return ImmutableSet.copyOf(
-                implicitDependencies.isEmpty()
-                    ? explicitDependencies()
-                    : Sets.union(implicitDependencies, explicitDependencies()));
-          });
-
-  /**
-   * The set of {@link DependencyRequest dependencies} required to satisfy this binding. This is the
-   * union of {@link #explicitDependencies()} and {@link #implicitDependencies()}. This returns an
-   * unmodifiable set.
-   */
-  final ImmutableSet<DependencyRequest> dependencies() {
-    return dependencies.get();
-  }
-
-  private final Supplier<ImmutableList<FrameworkDependency>> frameworkDependencies =
-      memoize(
-          () ->
-              dependencyAssociations()
-                  .stream()
-                  .map(DependencyAssociation::frameworkDependency)
-                  .collect(toImmutableList()));
-
-  /**
-   * The framework dependencies of {@code binding}. There will be one element for each different
-   * binding key in the <em>{@linkplain Binding#unresolved() unresolved}</em> version of {@code
-   * binding}.
-   *
-   * <p>For example, given the following modules:
-   *
-   * <pre><code>
-   *   {@literal @Module} abstract class {@literal BaseModule<T>} {
-   *     {@literal @Provides} Foo provideFoo(T t, String string) {
-   *       return …;
-   *     }
-   *   }
-   *
-   *   {@literal @Module} class StringModule extends {@literal BaseModule<String>} {}
-   * </code></pre>
-   *
-   * Both dependencies of {@code StringModule.provideFoo} have the same binding key: {@code String}.
-   * But there are still two dependencies, because in the unresolved binding they have different
-   * binding keys:
-   *
-   * <dl>
-   *   <dt>{@code T}
-   *   <dd>{@code String t}
-   *   <dt>{@code String}
-   *   <dd>{@code String string}
-   * </dl>
-   *
-   * <p>Note that the sets returned by this method when called on the same binding will be equal,
-   * and their elements will be in the same order.
-   */
-  /* TODO(dpb): The stable-order postcondition is actually hard to verify in code for two equal
-   * instances of Binding, because it really depends on the order of the binding's dependencies,
-   * and two equal instances of Binding may have the same dependencies in a different order. */
-  final ImmutableList<FrameworkDependency> frameworkDependencies() {
-    return frameworkDependencies.get();
-  }
-
-  /**
-   * Associates a {@link FrameworkDependency} with the set of {@link DependencyRequest} instances
-   * that correlate for a binding.
-   */
-  @AutoValue
-  abstract static class DependencyAssociation {
-    abstract FrameworkDependency frameworkDependency();
-
-    abstract ImmutableSet<DependencyRequest> dependencyRequests();
-
-    static DependencyAssociation create(
-        FrameworkDependency frameworkDependency, Iterable<DependencyRequest> dependencyRequests) {
-      return new AutoValue_Binding_DependencyAssociation(
-          frameworkDependency, ImmutableSet.copyOf(dependencyRequests));
-    }
-  }
-
-  private final Supplier<ImmutableList<DependencyAssociation>> dependencyAssociations =
-      memoize(
-          () -> {
-            FrameworkTypeMapper frameworkTypeMapper =
-                FrameworkTypeMapper.forBindingType(bindingType());
-            ImmutableList.Builder<DependencyAssociation> list = ImmutableList.builder();
-            for (Set<DependencyRequest> requests : groupByUnresolvedKey()) {
-              list.add(
-                  DependencyAssociation.create(
-                      FrameworkDependency.create(
-                          getOnlyElement(
-                              requests.stream().map(DependencyRequest::key).collect(toSet())),
-                          frameworkTypeMapper.getFrameworkType(requests)),
-                      requests));
-            }
-            return list.build();
-          });
-
-  /**
-   * Returns the same {@link FrameworkDependency} instances from {@link #frameworkDependencies}, but
-   * with the set of {@link DependencyRequest} instances with which each is associated.
-   *
-   * <p>Ths method returns a list of {@link Map.Entry entries} rather than a {@link Map} or {@link
-   * com.google.common.collect.Multimap} because any given {@link FrameworkDependency} may appear
-   * multiple times if the {@linkplain Binding#unresolved() unresolved} binding requires it. If that
-   * distinction is not important, the entries can be merged into a single mapping.
-   */
-  final ImmutableList<DependencyAssociation> dependencyAssociations() {
-    return dependencyAssociations.get();
-  }
-
-  private final Supplier<ImmutableMap<DependencyRequest, FrameworkDependency>>
-      frameworkDependenciesMap =
-          memoize(
-              () -> {
-                ImmutableMap.Builder<DependencyRequest, FrameworkDependency> frameworkDependencies =
-                    ImmutableMap.builder();
-                for (DependencyAssociation dependencyAssociation : dependencyAssociations()) {
-                  for (DependencyRequest dependencyRequest :
-                      dependencyAssociation.dependencyRequests()) {
-                    frameworkDependencies.put(
-                        dependencyRequest, dependencyAssociation.frameworkDependency());
-                  }
-                }
-                return frameworkDependencies.build();
-              });
-
-  /**
-   * Returns the mapping from each {@linkplain #dependencies dependency} to its associated {@link
-   * FrameworkDependency}.
-   */
-  final ImmutableMap<DependencyRequest, FrameworkDependency>
-      dependenciesToFrameworkDependenciesMap() {
-    return frameworkDependenciesMap.get();
-  }
-
-  /**
-   * Groups {@code binding}'s implicit dependencies by their binding key, using the dependency keys
-   * from the {@link Binding#unresolved()} binding if it exists.
-   */
-  private ImmutableList<Set<DependencyRequest>> groupByUnresolvedKey() {
-    ImmutableSetMultimap.Builder<Key, DependencyRequest> dependenciesByKeyBuilder =
-        ImmutableSetMultimap.builder();
-    Iterator<DependencyRequest> dependencies = dependencies().iterator();
-    Binding unresolved = unresolved().isPresent() ? unresolved().get() : this;
-    Iterator<DependencyRequest> unresolvedDependencies = unresolved.dependencies().iterator();
-    while (dependencies.hasNext()) {
-      dependenciesByKeyBuilder.put(unresolvedDependencies.next().key(), dependencies.next());
-    }
-    return ImmutableList.copyOf(
-        Multimaps.asMap(
-                dependenciesByKeyBuilder.orderValuesBy(SourceFiles.DEPENDENCY_ORDERING).build())
-            .values());
-  }
-
-  /**
-   * If this binding's key's type parameters are different from those of the
-   * {@link #bindingTypeElement()}, this is the binding for the {@link #bindingTypeElement()}'s
-   * unresolved type.
-   */
-  abstract Optional<? extends Binding> unresolved();
-
-  Optional<Scope> scope() {
-    return Optional.empty();
-  }
-
-  // TODO(sameb): Remove the TypeElement parameter and pull it from the TypeMirror.
-  static boolean hasNonDefaultTypeParameters(
-      TypeElement element, TypeMirror type, DaggerTypes types) {
-    // If the element has no type parameters, nothing can be wrong.
-    if (element.getTypeParameters().isEmpty()) {
-      return false;
-    }
-
-    List<TypeMirror> defaultTypes = Lists.newArrayList();
-    for (TypeParameterElement parameter : element.getTypeParameters()) {
-      defaultTypes.add(parameter.asType());
-    }
-
-    List<TypeMirror> actualTypes =
-        type.accept(
-            new SimpleTypeVisitor6<List<TypeMirror>, Void>() {
-              @Override
-              protected List<TypeMirror> defaultAction(TypeMirror e, Void p) {
-                return ImmutableList.of();
-              }
-
-              @Override
-              public List<TypeMirror> visitDeclared(DeclaredType t, Void p) {
-                return ImmutableList.<TypeMirror>copyOf(t.getTypeArguments());
-              }
-            },
-            null);
-
-    // The actual type parameter size can be different if the user is using a raw type.
-    if (defaultTypes.size() != actualTypes.size()) {
-      return true;
-    }
-
-    for (int i = 0; i < defaultTypes.size(); i++) {
-      if (!types.isSameType(defaultTypes.get(i), actualTypes.get(i))) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingDeclaration.java b/java/dagger/internal/codegen/BindingDeclaration.java
deleted file mode 100644
index c9520cd..0000000
--- a/java/dagger/internal/codegen/BindingDeclaration.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.BindingKind;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/** An object that declares or specifies a binding. */
-abstract class BindingDeclaration {
-
-  /** The {@link Key} of this declaration. */
-  abstract Key key();
-
-  /**
-   * The {@link Element} that declares this binding. Absent for {@linkplain BindingKind binding
-   * kinds} that are not always declared by exactly one element.
-   *
-   * <p>For example, consider {@link BindingKind#MULTIBOUND_SET}. A component with many
-   * {@code @IntoSet} bindings for the same key will have a synthetic binding that depends on all
-   * contributions, but with no identifiying binding element. A {@code @Multibinds} method will also
-   * contribute a synthetic binding, but since multiple {@code @Multibinds} methods can coexist in
-   * the same component (and contribute to one single binding), it has no binding element.
-   */
-  // TODO(ronshapiro): examine whether this wildcard+bound have any benefit.
-  // We never actually refer to the overridden bindingElement methods directly in a way which needs
-  // anything more than an Element. Removing the wildcard would allow for simpler user-written code
-  // when the binding element is passed to a method.
-  abstract Optional<Element> bindingElement();
-
-  /**
-   * The type enclosing the {@link #bindingElement()}, or {@link Optional#empty()} if {@link
-   * #bindingElement()} is empty.
-   */
-  final Optional<TypeElement> bindingTypeElement() {
-    return bindingElement().map(DaggerElements::closestEnclosingTypeElement);
-  }
-  
-  /**
-   * The installed module class that contributed the {@link #bindingElement()}. May be a subclass of
-   * the class that contains {@link #bindingElement()}. Absent if {@link #bindingElement()} is
-   * empty.
-   */
-  abstract Optional<TypeElement> contributingModule();
-}
diff --git a/java/dagger/internal/codegen/BindingDeclarationFormatter.java b/java/dagger/internal/codegen/BindingDeclarationFormatter.java
deleted file mode 100644
index d850165..0000000
--- a/java/dagger/internal/codegen/BindingDeclarationFormatter.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2015 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.collect.Sets.immutableEnumSet;
-import static dagger.internal.codegen.DiagnosticFormatting.stripCommonTypePrefixes;
-import static dagger.internal.codegen.ElementFormatter.elementToString;
-import static javax.lang.model.element.ElementKind.PARAMETER;
-import static javax.lang.model.type.TypeKind.DECLARED;
-import static javax.lang.model.type.TypeKind.EXECUTABLE;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeKind;
-
-/**
- * Formats a {@link BindingDeclaration} into a {@link String} suitable for use in error messages.
- */
-final class BindingDeclarationFormatter extends Formatter<BindingDeclaration> {
-  private static final ImmutableSet<TypeKind> FORMATTABLE_ELEMENT_TYPE_KINDS =
-      immutableEnumSet(EXECUTABLE, DECLARED);
-
-  private final MethodSignatureFormatter methodSignatureFormatter;
-
-  @Inject
-  BindingDeclarationFormatter(MethodSignatureFormatter methodSignatureFormatter) {
-    this.methodSignatureFormatter = methodSignatureFormatter;
-  }
-
-  /**
-   * Returns {@code true} for declarations that this formatter can format. Specifically bindings
-   * from subcomponent declarations or those with {@linkplain BindingDeclaration#bindingElement()
-   * binding elements} that are methods, constructors, or types.
-   */
-  boolean canFormat(BindingDeclaration bindingDeclaration) {
-    if (bindingDeclaration instanceof SubcomponentDeclaration) {
-      return true;
-    }
-    if (bindingDeclaration.bindingElement().isPresent()) {
-      Element bindingElement = bindingDeclaration.bindingElement().get();
-      return bindingElement.getKind().equals(PARAMETER)
-          || FORMATTABLE_ELEMENT_TYPE_KINDS.contains(bindingElement.asType().getKind());
-    }
-    // TODO(dpb): validate whether what this is doing is correct
-    return false;
-  }
-
-  @Override
-  public String format(BindingDeclaration bindingDeclaration) {
-    if (bindingDeclaration instanceof SubcomponentDeclaration) {
-      return formatSubcomponentDeclaration((SubcomponentDeclaration) bindingDeclaration);
-    }
-
-    if (bindingDeclaration.bindingElement().isPresent()) {
-      Element bindingElement = bindingDeclaration.bindingElement().get();
-      if (bindingElement.getKind().equals(PARAMETER)) {
-        return elementToString(bindingElement);
-      }
-
-      switch (bindingElement.asType().getKind()) {
-        case EXECUTABLE:
-          return methodSignatureFormatter.format(
-              MoreElements.asExecutable(bindingElement),
-              bindingDeclaration
-                  .contributingModule()
-                  .map(module -> MoreTypes.asDeclared(module.asType())));
-
-        case DECLARED:
-          return stripCommonTypePrefixes(bindingElement.asType().toString());
-
-        default:
-          throw new IllegalArgumentException(
-              "Formatting unsupported for element: " + bindingElement);
-      }
-    }
-
-    return String.format(
-        "Dagger-generated binding for %s",
-        stripCommonTypePrefixes(bindingDeclaration.key().toString()));
-  }
-
-  private String formatSubcomponentDeclaration(SubcomponentDeclaration subcomponentDeclaration) {
-    ImmutableList<TypeElement> moduleSubcomponents =
-        subcomponentDeclaration.moduleAnnotation().subcomponents();
-    int index = moduleSubcomponents.indexOf(subcomponentDeclaration.subcomponentType());
-    StringBuilder annotationValue = new StringBuilder();
-    if (moduleSubcomponents.size() != 1) {
-      annotationValue.append("{");
-    }
-    annotationValue.append(
-        formatArgumentInList(
-            index,
-            moduleSubcomponents.size(),
-            subcomponentDeclaration.subcomponentType().getQualifiedName() + ".class"));
-    if (moduleSubcomponents.size() != 1) {
-      annotationValue.append("}");
-    }
-
-    return String.format(
-        "@%s(subcomponents = %s) for %s",
-        subcomponentDeclaration.moduleAnnotation().annotationClass().getSimpleName(),
-        annotationValue,
-        subcomponentDeclaration.contributingModule().get());
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingElementValidator.java b/java/dagger/internal/codegen/BindingElementValidator.java
deleted file mode 100644
index 0051912..0000000
--- a/java/dagger/internal/codegen/BindingElementValidator.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2016 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.Verify.verifyNotNull;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
-import static dagger.internal.codegen.MapKeys.getMapKeys;
-import static dagger.internal.codegen.Scopes.scopesOf;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnnotationMirror;
-import static javax.lang.model.type.TypeKind.ARRAY;
-import static javax.lang.model.type.TypeKind.DECLARED;
-import static javax.lang.model.type.TypeKind.TYPEVAR;
-import static javax.lang.model.type.TypeKind.VOID;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.errorprone.annotations.FormatMethod;
-import dagger.MapKey;
-import dagger.Provides;
-import dagger.model.Key;
-import dagger.model.Scope;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.producers.Produces;
-import java.lang.annotation.Annotation;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.inject.Qualifier;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for elements that represent binding declarations. */
-abstract class BindingElementValidator<E extends Element> {
-  private final Class<? extends Annotation> bindingAnnotation;
-  private final AllowsMultibindings allowsMultibindings;
-  private final AllowsScoping allowsScoping;
-  private final Map<E, ValidationReport<E>> cache = new HashMap<>();
-
-  /**
-   * Creates a validator object.
-   *
-   * @param bindingAnnotation the annotation on an element that identifies it as a binding element
-   */
-  protected BindingElementValidator(
-      Class<? extends Annotation> bindingAnnotation,
-      AllowsMultibindings allowsMultibindings,
-      AllowsScoping allowsScoping) {
-    this.bindingAnnotation = bindingAnnotation;
-    this.allowsMultibindings = allowsMultibindings;
-    this.allowsScoping = allowsScoping;
-  }
-
-  /** Returns a {@link ValidationReport} for {@code element}. */
-  final ValidationReport<E> validate(E element) {
-    return reentrantComputeIfAbsent(cache, element, this::validateUncached);
-  }
-
-  private ValidationReport<E> validateUncached(E element) {
-    return elementValidator(element).validate();
-  }
-
-  /**
-   * Returns an error message of the form "&lt;{@link #bindingElements()}&gt; <i>rule</i>", where
-   * <i>rule</i> comes from calling {@link String#format(String, Object...)} on {@code ruleFormat}
-   * and the other arguments.
-   */
-  @FormatMethod
-  protected final String bindingElements(String ruleFormat, Object... args) {
-    return new Formatter().format("%s ", bindingElements()).format(ruleFormat, args).toString();
-  }
-
-  /**
-   * The kind of elements that this validator validates. Should be plural. Used for error reporting.
-   */
-  protected abstract String bindingElements();
-
-  /** The verb describing the {@link ElementValidator#bindingElementType()} in error messages. */
-  // TODO(ronshapiro,dpb): improve the name of this method and it's documentation.
-  protected abstract String bindingElementTypeVerb();
-
-  /** The error message when a binding element has a bad type. */
-  protected String badTypeMessage() {
-    return bindingElements(
-        "must %s a primitive, an array, a type variable, or a declared type",
-        bindingElementTypeVerb());
-  }
-
-  /**
-   * The error message when a the type for a binding element with {@link
-   * ElementsIntoSet @ElementsIntoSet} or {@code SET_VALUES} is a not set type.
-   */
-  protected String elementsIntoSetNotASetMessage() {
-    return bindingElements(
-        "annotated with @ElementsIntoSet must %s a Set", bindingElementTypeVerb());
-  }
-
-  /**
-   * The error message when a the type for a binding element with {@link
-   * ElementsIntoSet @ElementsIntoSet} or {@code SET_VALUES} is a raw set.
-   */
-  protected String elementsIntoSetRawSetMessage() {
-    return bindingElements(
-        "annotated with @ElementsIntoSet cannot %s a raw Set", bindingElementTypeVerb());
-  }
-
-  /*** Returns an {@link ElementValidator} for validating the given {@code element}. */
-  protected abstract ElementValidator elementValidator(E element);
-
-  /** Validator for a single binding element. */
-  protected abstract class ElementValidator {
-    protected final E element;
-    protected final ValidationReport.Builder<E> report;
-
-    protected ElementValidator(E element) {
-      this.element = element;
-      this.report = ValidationReport.about(element);
-    }
-
-    /** Checks the element for validity. */
-    private ValidationReport<E> validate() {
-      checkType();
-      checkQualifiers();
-      checkMapKeys();
-      checkMultibindings();
-      checkScopes();
-      checkAdditionalProperties();
-      return report.build();
-    }
-
-    /** Check any additional properties of the element. Does nothing by default. */
-    protected void checkAdditionalProperties() {}
-
-    /**
-     * The type declared by this binding element. This may differ from a binding's {@link
-     * Key#type()}, for example in multibindings. An {@link Optional#empty()} return value indicates
-     * that the contributed type is ambiguous or missing, i.e. a {@code @BindsInstance} method with
-     * zero or many parameters.
-     */
-    // TODO(dpb): should this be an ImmutableList<TypeMirror>, with this class checking the size?
-    protected abstract Optional<TypeMirror> bindingElementType();
-
-    /**
-     * Adds an error if the {@link #bindingElementType() binding element type} is not appropriate.
-     *
-     * <p>Adds an error if the type is not a primitive, array, declared type, or type variable.
-     *
-     * <p>If the binding is not a multibinding contribution, adds an error if the type is a
-     * framework type.
-     *
-     * <p>If the element has {@link ElementsIntoSet @ElementsIntoSet} or {@code SET_VALUES}, adds an
-     * error if the type is not a {@code Set<T>} for some {@code T}
-     */
-    protected void checkType() {
-      switch (ContributionType.fromBindingElement(element)) {
-        case UNIQUE:
-          /* Validate that a unique binding is not attempting to bind a framework type. This
-           * validation is only appropriate for unique bindings because multibindings may collect
-           * framework types.  E.g. Set<Provider<Foo>> is perfectly reasonable. */
-          checkFrameworkType();
-          // fall through
-
-        case SET:
-        case MAP:
-          bindingElementType().ifPresent(type -> checkKeyType(type));
-          break;
-
-        case SET_VALUES:
-          checkSetValuesType();
-      }
-    }
-
-    /**
-     * Adds an error if {@code keyType} is not a primitive, declared type, array, or type variable.
-     */
-    protected void checkKeyType(TypeMirror keyType) {
-      TypeKind kind = keyType.getKind();
-      if (kind.equals(VOID)) {
-        report.addError(bindingElements("must %s a value (not void)", bindingElementTypeVerb()));
-      } else if (!(kind.isPrimitive()
-          || kind.equals(DECLARED)
-          || kind.equals(ARRAY)
-          || kind.equals(TYPEVAR))) {
-        report.addError(badTypeMessage());
-      }
-    }
-
-    /**
-     * Adds an error if the type for an element with {@link ElementsIntoSet @ElementsIntoSet} or
-     * {@code SET_VALUES} is not a a {@code Set<T>} for a reasonable {@code T}.
-     */
-    // TODO(gak): should we allow "covariant return" for set values?
-    protected void checkSetValuesType() {
-      bindingElementType().ifPresent(keyType -> checkSetValuesType(keyType));
-    }
-
-    /** Adds an error if {@code type} is not a {@code Set<T>} for a reasonable {@code T}. */
-    protected final void checkSetValuesType(TypeMirror type) {
-      if (!SetType.isSet(type)) {
-        report.addError(elementsIntoSetNotASetMessage());
-      } else {
-        SetType setType = SetType.from(type);
-        if (setType.isRawType()) {
-          report.addError(elementsIntoSetRawSetMessage());
-        } else {
-          checkKeyType(setType.elementType());
-        }
-      }
-    }
-
-    /**
-     * Adds an error if the element has more than one {@linkplain Qualifier qualifier} annotation.
-     */
-    private void checkQualifiers() {
-      ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(element);
-      if (qualifiers.size() > 1) {
-        for (AnnotationMirror qualifier : qualifiers) {
-          report.addError(
-              bindingElements("may not use more than one @Qualifier"),
-              element,
-              qualifier);
-        }
-      }
-    }
-
-    /**
-     * Adds an error if an {@link IntoMap @IntoMap} element doesn't have exactly one {@link
-     * MapKey @MapKey} annotation, or if an element that is {@link IntoMap @IntoMap} has any.
-     */
-    private void checkMapKeys() {
-      if (!allowsMultibindings.allowsMultibindings()) {
-        return;
-      }
-      ImmutableSet<? extends AnnotationMirror> mapKeys = getMapKeys(element);
-      if (ContributionType.fromBindingElement(element).equals(ContributionType.MAP)) {
-        switch (mapKeys.size()) {
-          case 0:
-            report.addError(bindingElements("of type map must declare a map key"));
-            break;
-          case 1:
-            break;
-          default:
-            report.addError(bindingElements("may not have more than one map key"));
-            break;
-        }
-      } else if (!mapKeys.isEmpty()) {
-        report.addError(bindingElements("of non map type cannot declare a map key"));
-      }
-    }
-
-    /**
-     * Adds errors if:
-     *
-     * <ul>
-     *   <li>the element doesn't allow {@linkplain MultibindingAnnotations multibinding annotations}
-     *       and has any
-     *   <li>the element does allow them but has more than one
-     *   <li>the element has a multibinding annotation and its {@link Provides} or {@link Produces}
-     *       annotation has a {@code type} parameter.
-     * </ul>
-     */
-    private void checkMultibindings() {
-      ImmutableSet<AnnotationMirror> multibindingAnnotations =
-          MultibindingAnnotations.forElement(element);
-
-      switch (allowsMultibindings) {
-        case NO_MULTIBINDINGS:
-          for (AnnotationMirror annotation : multibindingAnnotations) {
-            report.addError(
-                bindingElements("cannot have multibinding annotations"),
-                element,
-                annotation);
-          }
-          break;
-
-        case ALLOWS_MULTIBINDINGS:
-          if (multibindingAnnotations.size() > 1) {
-            for (AnnotationMirror annotation : multibindingAnnotations) {
-              report.addError(
-                  bindingElements("cannot have more than one multibinding annotation"),
-                  element,
-                  annotation);
-            }
-          }
-          break;
-      }
-
-      // TODO(ronshapiro): move this into ProvidesMethodValidator
-      if (bindingAnnotation.equals(Provides.class)) {
-        AnnotationMirror bindingAnnotationMirror =
-            getAnnotationMirror(element, bindingAnnotation).get();
-        boolean usesProvidesType = false;
-        for (ExecutableElement member : bindingAnnotationMirror.getElementValues().keySet()) {
-          usesProvidesType |= member.getSimpleName().contentEquals("type");
-        }
-        if (usesProvidesType && !multibindingAnnotations.isEmpty()) {
-          report.addError(
-              "@Provides.type cannot be used with multibinding annotations", element);
-        }
-      }
-    }
-
-    /**
-     * Adds an error if the element has a scope but doesn't allow scoping, or if it has more than
-     * one {@linkplain Scope scope} annotation.
-     */
-    private void checkScopes() {
-      ImmutableSet<Scope> scopes = scopesOf(element);
-      String error = null;
-      switch (allowsScoping) {
-        case ALLOWS_SCOPING:
-          if (scopes.size() <= 1) {
-            return;
-          }
-          error = bindingElements("cannot use more than one @Scope");
-          break;
-        case NO_SCOPING:
-          error = bindingElements("cannot be scoped");
-          break;
-      }
-      verifyNotNull(error);
-      for (Scope scope : scopes) {
-        report.addError(error, element, scope.scopeAnnotation());
-      }
-    }
-
-    /**
-     * Adds an error if the {@link #bindingElementType() type} is a {@linkplain FrameworkTypes
-     * framework type}.
-     */
-    private void checkFrameworkType() {
-      if (bindingElementType().filter(FrameworkTypes::isFrameworkType).isPresent()) {
-        report.addError(bindingElements("must not %s framework types", bindingElementTypeVerb()));
-      }
-    }
-  }
-
-  /** Whether to check multibinding annotations. */
-  enum AllowsMultibindings {
-    /**
-     * This element disallows multibinding annotations, so don't bother checking for their validity.
-     * {@link MultibindingAnnotationsProcessingStep} will add errors if the element has any
-     * multibinding annotations.
-     */
-    NO_MULTIBINDINGS,
-
-    /** This element allows multibinding annotations, so validate them. */
-    ALLOWS_MULTIBINDINGS,
-    ;
-
-    private boolean allowsMultibindings() {
-      return this == ALLOWS_MULTIBINDINGS;
-    }
-  }
-
-  /** How to check scoping annotations. */
-  enum AllowsScoping {
-    /** This element disallows scoping, so check that no scope annotations are present. */
-    NO_SCOPING,
-
-    /** This element allows scoping, so validate that there's at most one scope annotation. */
-    ALLOWS_SCOPING,
-    ;
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingExpression.java b/java/dagger/internal/codegen/BindingExpression.java
deleted file mode 100644
index 65200f7..0000000
--- a/java/dagger/internal/codegen/BindingExpression.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2017 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 dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.lang.model.type.TypeMirror;
-
-/** A factory of code expressions used to access a single request for a binding in a component. */
-// TODO(user): Rename this to RequestExpression?
-abstract class BindingExpression {
-
-  /**
-   * Returns an expression that evaluates to the value of a request based on the given requesting
-   * class.
-   *
-   * @param requestingClass the class that will contain the expression
-   */
-  abstract Expression getDependencyExpression(ClassName requestingClass);
-
-  /**
-   * Equivalent to {@link #getDependencyExpression} that is used only when the request is for an
-   * implementation of a component method. By default, just delegates to {@link
-   * #getDependencyExpression}.
-   */
-  Expression getDependencyExpressionForComponentMethod(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    return getDependencyExpression(component.name());
-  }
-
-  /** Returns {@code true} if this binding expression should be encapsulated in a method. */
-  boolean requiresMethodEncapsulation() {
-    return false;
-  }
-
-  /**
-   * Returns an expression for the implementation of a component method with the given request.
-   *
-   * @param component the component that will contain the implemented method
-   */
-  CodeBlock getComponentMethodImplementation(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    // By default, just delegate to #getDependencyExpression().
-    return CodeBlock.of(
-        "return $L;",
-        getDependencyExpressionForComponentMethod(componentMethod, component).codeBlock());
-  }
-
-  /**
-   * Returns an expression for the implementation of a modifiable binding method for the given
-   * component.
-   */
-  CodeBlock getModifiableBindingMethodImplementation(
-      ModifiableBindingMethod modifiableBindingMethod,
-      ComponentImplementation component,
-      DaggerTypes types) {
-    Expression dependencyExpression = getDependencyExpression(component.name());
-
-    // It's possible to have a case where a modifiable component method delegates to another
-    // binding method from an enclosing class that is not itself a component method. In that case,
-    // the enclosing class's method may return a publicly accessible type, but the nested class will
-    // have a return type that is defined by the component method. In that case, a downcast is
-    // necessary so that the return statement is valid.
-    //
-    // E.g.:
-    //
-    // public class DaggerAncestor implements Ancestor {
-    //   protected Object packagePrivateModifiable() { ... }
-    //
-    //   protected class LeafImpl extends DaggerLeaf {
-    //     @Override
-    //     public final PackagePrivateModifiable componentMethod() {
-    //       return (PackagePrivateModifiable) DaggerAncestor.this.packagePrivateModifiable();
-    //     }
-    //   }
-    // }
-    //
-    // DaggerAncestor.packagePrivateModifiable returns Object even though the actual instance's type
-    // is PackagePrivateModifiable. So a cast is necessary.
-    //
-    // This isn't necessary for getComponentMethodImplementation() because that's only used for
-    // non-modifiable bindings
-    TypeMirror returnType = modifiableBindingMethod.returnType();
-    if (!types.isAssignable(dependencyExpression.type(), returnType)
-       && isTypeAccessibleFrom(returnType, component.name().packageName())) {
-      dependencyExpression = dependencyExpression.castTo(returnType);
-    }
-
-    return CodeBlock.of("return $L;", dependencyExpression.codeBlock());
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingFactory.java b/java/dagger/internal/codegen/BindingFactory.java
deleted file mode 100644
index 564b412..0000000
--- a/java/dagger/internal/codegen/BindingFactory.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2017 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.auto.common.MoreTypes.asDeclared;
-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 com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.Binding.hasNonDefaultTypeParameters;
-import static dagger.internal.codegen.ComponentDescriptor.isComponentProductionMethod;
-import static dagger.internal.codegen.ConfigurationAnnotations.getNullableType;
-import static dagger.internal.codegen.ContributionBinding.bindingKindForMultibindingKey;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
-import static dagger.internal.codegen.MapKeys.getMapKey;
-import static dagger.internal.codegen.MoreAnnotationMirrors.wrapOptionalInEquivalence;
-import static dagger.internal.codegen.Scopes.uniqueScopeOf;
-import static dagger.model.BindingKind.BOUND_INSTANCE;
-import static dagger.model.BindingKind.COMPONENT;
-import static dagger.model.BindingKind.COMPONENT_DEPENDENCY;
-import static dagger.model.BindingKind.COMPONENT_PRODUCTION;
-import static dagger.model.BindingKind.COMPONENT_PROVISION;
-import static dagger.model.BindingKind.DELEGATE;
-import static dagger.model.BindingKind.INJECTION;
-import static dagger.model.BindingKind.MEMBERS_INJECTOR;
-import static dagger.model.BindingKind.OPTIONAL;
-import static dagger.model.BindingKind.PRODUCTION;
-import static dagger.model.BindingKind.PROVISION;
-import static dagger.model.BindingKind.SUBCOMPONENT_CREATOR;
-import static javax.lang.model.element.ElementKind.CONSTRUCTOR;
-import static javax.lang.model.element.ElementKind.METHOD;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import dagger.Module;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.internal.codegen.ProductionBinding.ProductionKind;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.Optional;
-import java.util.function.BiFunction;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/** A factory for {@link Binding} objects. */
-final class BindingFactory {
-  private final DaggerTypes types;
-  private final KeyFactory keyFactory;
-  private final DependencyRequestFactory dependencyRequestFactory;
-  private final InjectionSiteFactory injectionSiteFactory;
-  private final DaggerElements elements;
-
-  @Inject
-  BindingFactory(
-      DaggerTypes types,
-      DaggerElements elements,
-      KeyFactory keyFactory,
-      DependencyRequestFactory dependencyRequestFactory,
-      InjectionSiteFactory injectionSiteFactory) {
-    this.types = types;
-    this.elements = elements;
-    this.keyFactory = keyFactory;
-    this.dependencyRequestFactory = dependencyRequestFactory;
-    this.injectionSiteFactory = injectionSiteFactory;
-  }
-
-  /**
-   * Returns an {@link dagger.model.BindingKind#INJECTION} binding.
-   *
-   * @param constructorElement the {@code @Inject}-annotated constructor
-   * @param resolvedType the parameterized type if the constructor is for a generic class and the
-   *     binding should be for the parameterized type
-   */
-  // TODO(dpb): See if we can just pass the parameterized type and not also the constructor.
-  ProvisionBinding injectionBinding(
-      ExecutableElement constructorElement, Optional<TypeMirror> resolvedType) {
-    checkArgument(constructorElement.getKind().equals(CONSTRUCTOR));
-    checkArgument(isAnnotationPresent(constructorElement, Inject.class));
-    checkArgument(!getQualifier(constructorElement).isPresent());
-
-    ExecutableType constructorType = MoreTypes.asExecutable(constructorElement.asType());
-    DeclaredType constructedType =
-        MoreTypes.asDeclared(constructorElement.getEnclosingElement().asType());
-    // If the class this is constructing has some type arguments, resolve everything.
-    if (!constructedType.getTypeArguments().isEmpty() && resolvedType.isPresent()) {
-      DeclaredType resolved = MoreTypes.asDeclared(resolvedType.get());
-      // Validate that we're resolving from the correct type.
-      checkState(
-          types.isSameType(types.erasure(resolved), types.erasure(constructedType)),
-          "erased expected type: %s, erased actual type: %s",
-          types.erasure(resolved),
-          types.erasure(constructedType));
-      constructorType = MoreTypes.asExecutable(types.asMemberOf(resolved, constructorElement));
-      constructedType = resolved;
-    }
-
-    Key key = keyFactory.forInjectConstructorWithResolvedType(constructedType);
-    ImmutableSet<DependencyRequest> provisionDependencies =
-        dependencyRequestFactory.forRequiredResolvedVariables(
-            constructorElement.getParameters(), constructorType.getParameterTypes());
-
-    ProvisionBinding.Builder builder =
-        ProvisionBinding.builder()
-            .contributionType(ContributionType.UNIQUE)
-            .bindingElement(constructorElement)
-            .key(key)
-            .provisionDependencies(provisionDependencies)
-            .injectionSites(injectionSiteFactory.getInjectionSites(constructedType))
-            .kind(INJECTION)
-            .scope(uniqueScopeOf(constructorElement.getEnclosingElement()));
-
-    TypeElement bindingTypeElement = MoreElements.asType(constructorElement.getEnclosingElement());
-    if (hasNonDefaultTypeParameters(bindingTypeElement, key.type(), types)) {
-      builder.unresolved(injectionBinding(constructorElement, Optional.empty()));
-    }
-    return builder.build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#PROVISION} binding for a {@code @Provides}-annotated
-   * method.
-   *
-   * @param contributedBy the installed module that declares or inherits the method
-   */
-  ProvisionBinding providesMethodBinding(
-      ExecutableElement providesMethod, TypeElement contributedBy) {
-    return setMethodBindingProperties(
-            ProvisionBinding.builder(),
-            providesMethod,
-            contributedBy,
-            keyFactory.forProvidesMethod(providesMethod, contributedBy),
-            this::providesMethodBinding)
-        .kind(PROVISION)
-        .scope(uniqueScopeOf(providesMethod))
-        .nullableType(getNullableType(providesMethod))
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#PRODUCTION} binding for a {@code @Produces}-annotated
-   * method.
-   *
-   * @param contributedBy the installed module that declares or inherits the method
-   */
-  ProductionBinding producesMethodBinding(
-      ExecutableElement producesMethod, TypeElement contributedBy) {
-    // TODO(beder): Add nullability checking with Java 8.
-    ProductionBinding.Builder builder =
-        setMethodBindingProperties(
-                ProductionBinding.builder(),
-                producesMethod,
-                contributedBy,
-                keyFactory.forProducesMethod(producesMethod, contributedBy),
-                this::producesMethodBinding)
-            .kind(PRODUCTION)
-            .productionKind(ProductionKind.fromProducesMethod(producesMethod))
-            .thrownTypes(producesMethod.getThrownTypes())
-            .executorRequest(dependencyRequestFactory.forProductionImplementationExecutor())
-            .monitorRequest(dependencyRequestFactory.forProductionComponentMonitor());
-    return builder.build();
-  }
-
-  private <C extends ContributionBinding, B extends ContributionBinding.Builder<C, B>>
-      B setMethodBindingProperties(
-          B builder,
-          ExecutableElement method,
-          TypeElement contributedBy,
-          Key key,
-          BiFunction<ExecutableElement, TypeElement, C> create) {
-    checkArgument(method.getKind().equals(METHOD));
-    ExecutableType methodType =
-        MoreTypes.asExecutable(
-            types.asMemberOf(MoreTypes.asDeclared(contributedBy.asType()), method));
-    if (!types.isSameType(methodType, method.asType())) {
-      builder.unresolved(create.apply(method, MoreElements.asType(method.getEnclosingElement())));
-    }
-    return builder
-        .contributionType(ContributionType.fromBindingElement(method))
-        .bindingElement(method)
-        .contributingModule(contributedBy)
-        .key(key)
-        .dependencies(
-            dependencyRequestFactory.forRequiredResolvedVariables(
-                method.getParameters(), methodType.getParameterTypes()))
-        .wrappedMapKeyAnnotation(wrapOptionalInEquivalence(getMapKey(method)));
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#MULTIBOUND_MAP} or {@link
-   * dagger.model.BindingKind#MULTIBOUND_SET} binding given a set of multibinding contribution
-   * bindings.
-   *
-   * @param key a key that may be satisfied by a multibinding
-   */
-  ContributionBinding syntheticMultibinding(
-      Key key, Iterable<ContributionBinding> multibindingContributions) {
-    ContributionBinding.Builder<?, ?> builder =
-        multibindingRequiresProduction(key, multibindingContributions)
-            ? ProductionBinding.builder()
-            : ProvisionBinding.builder();
-    return builder
-        .contributionType(ContributionType.UNIQUE)
-        .key(key)
-        .dependencies(
-            dependencyRequestFactory.forMultibindingContributions(key, multibindingContributions))
-        .kind(bindingKindForMultibindingKey(key))
-        .build();
-  }
-
-  private boolean multibindingRequiresProduction(
-      Key key, Iterable<ContributionBinding> multibindingContributions) {
-    if (MapType.isMap(key)) {
-      MapType mapType = MapType.from(key);
-      if (mapType.valuesAreTypeOf(Producer.class) || mapType.valuesAreTypeOf(Produced.class)) {
-        return true;
-      }
-    } else if (SetType.isSet(key) && SetType.from(key).elementsAreTypeOf(Produced.class)) {
-      return true;
-    }
-    return Iterables.any(
-        multibindingContributions, binding -> binding.bindingType().equals(BindingType.PRODUCTION));
-  }
-
-  /** Returns a {@link dagger.model.BindingKind#COMPONENT} binding for the component. */
-  ProvisionBinding componentBinding(TypeElement componentDefinitionType) {
-    checkNotNull(componentDefinitionType);
-    return ProvisionBinding.builder()
-        .contributionType(ContributionType.UNIQUE)
-        .bindingElement(componentDefinitionType)
-        .key(keyFactory.forType(componentDefinitionType.asType()))
-        .kind(COMPONENT)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#COMPONENT_DEPENDENCY} binding for a component's
-   * dependency.
-   */
-  ProvisionBinding componentDependencyBinding(ComponentRequirement dependency) {
-    checkNotNull(dependency);
-    return ProvisionBinding.builder()
-        .contributionType(ContributionType.UNIQUE)
-        .bindingElement(dependency.typeElement())
-        .key(keyFactory.forType(dependency.type()))
-        .kind(COMPONENT_DEPENDENCY)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#COMPONENT_PROVISION} or {@link
-   * dagger.model.BindingKind#COMPONENT_PRODUCTION} binding for a method on a component's
-   * dependency.
-   *
-   * @param componentDescriptor the component with the dependency, not the dependency that has the
-   *     method
-   */
-  ContributionBinding componentDependencyMethodBinding(
-      ComponentDescriptor componentDescriptor, ExecutableElement dependencyMethod) {
-    checkArgument(dependencyMethod.getKind().equals(METHOD));
-    checkArgument(dependencyMethod.getParameters().isEmpty());
-    ContributionBinding.Builder<?, ?> builder;
-    if (componentDescriptor.isProduction()
-        && isComponentProductionMethod(elements, dependencyMethod)) {
-      builder =
-          ProductionBinding.builder()
-              .key(keyFactory.forProductionComponentMethod(dependencyMethod))
-              .kind(COMPONENT_PRODUCTION)
-              .thrownTypes(dependencyMethod.getThrownTypes());
-    } else {
-      builder =
-          ProvisionBinding.builder()
-              .key(keyFactory.forComponentMethod(dependencyMethod))
-              .nullableType(getNullableType(dependencyMethod))
-              .kind(COMPONENT_PROVISION)
-              .scope(uniqueScopeOf(dependencyMethod));
-    }
-    return builder
-        .contributionType(ContributionType.UNIQUE)
-        .bindingElement(dependencyMethod)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#BOUND_INSTANCE} binding for a
-   * {@code @BindsInstance}-annotated builder setter method or factory method parameter.
-   */
-  ProvisionBinding boundInstanceBinding(ComponentRequirement requirement, Element element) {
-    checkArgument(element instanceof VariableElement || element instanceof ExecutableElement);
-    VariableElement parameterElement =
-        element instanceof VariableElement
-            ? MoreElements.asVariable(element)
-            : getOnlyElement(MoreElements.asExecutable(element).getParameters());
-    return ProvisionBinding.builder()
-        .contributionType(ContributionType.UNIQUE)
-        .bindingElement(element)
-        .key(requirement.key().get())
-        .nullableType(getNullableType(parameterElement))
-        .kind(BOUND_INSTANCE)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#SUBCOMPONENT_CREATOR} binding declared by a component
-   * method that returns a subcomponent builder. Use {{@link
-   * #subcomponentCreatorBinding(ImmutableSet)}} for bindings declared using {@link
-   * Module#subcomponents()}.
-   *
-   * @param component the component that declares or inherits the method
-   */
-  ProvisionBinding subcomponentCreatorBinding(
-      ExecutableElement subcomponentCreatorMethod, TypeElement component) {
-    checkArgument(subcomponentCreatorMethod.getKind().equals(METHOD));
-    checkArgument(subcomponentCreatorMethod.getParameters().isEmpty());
-    Key key =
-        keyFactory.forSubcomponentCreatorMethod(
-            subcomponentCreatorMethod, asDeclared(component.asType()));
-    return ProvisionBinding.builder()
-        .contributionType(ContributionType.UNIQUE)
-        .bindingElement(subcomponentCreatorMethod)
-        .key(key)
-        .kind(SUBCOMPONENT_CREATOR)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#SUBCOMPONENT_CREATOR} binding declared using {@link
-   * Module#subcomponents()}.
-   */
-  ProvisionBinding subcomponentCreatorBinding(
-      ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) {
-    SubcomponentDeclaration subcomponentDeclaration = subcomponentDeclarations.iterator().next();
-    return ProvisionBinding.builder()
-        .contributionType(ContributionType.UNIQUE)
-        .key(subcomponentDeclaration.key())
-        .kind(SUBCOMPONENT_CREATOR)
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#DELEGATE} binding.
-   *
-   * @param delegateDeclaration the {@code @Binds}-annotated declaration
-   * @param actualBinding the binding that satisfies the {@code @Binds} declaration
-   */
-  ContributionBinding delegateBinding(
-      DelegateDeclaration delegateDeclaration, ContributionBinding actualBinding) {
-    switch (actualBinding.bindingType()) {
-      case PRODUCTION:
-        return buildDelegateBinding(
-            ProductionBinding.builder().nullableType(actualBinding.nullableType()),
-            delegateDeclaration,
-            Producer.class);
-
-      case PROVISION:
-        return buildDelegateBinding(
-            ProvisionBinding.builder()
-                .scope(uniqueScopeOf(delegateDeclaration.bindingElement().get()))
-                .nullableType(actualBinding.nullableType()),
-            delegateDeclaration,
-            Provider.class);
-
-      case MEMBERS_INJECTION: // fall-through to throw
-    }
-    throw new AssertionError("bindingType: " + actualBinding);
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#DELEGATE} binding used when there is no binding that
-   * satisfies the {@code @Binds} declaration.
-   */
-  ContributionBinding unresolvedDelegateBinding(DelegateDeclaration delegateDeclaration) {
-    return buildDelegateBinding(
-        ProvisionBinding.builder().scope(uniqueScopeOf(delegateDeclaration.bindingElement().get())),
-        delegateDeclaration,
-        Provider.class);
-  }
-
-  private ContributionBinding buildDelegateBinding(
-      ContributionBinding.Builder<?, ?> builder,
-      DelegateDeclaration delegateDeclaration,
-      Class<?> frameworkType) {
-    return builder
-        .contributionType(delegateDeclaration.contributionType())
-        .bindingElement(delegateDeclaration.bindingElement().get())
-        .contributingModule(delegateDeclaration.contributingModule().get())
-        .key(keyFactory.forDelegateBinding(delegateDeclaration, frameworkType))
-        .dependencies(delegateDeclaration.delegateRequest())
-        .wrappedMapKeyAnnotation(delegateDeclaration.wrappedMapKey())
-        .kind(DELEGATE)
-        .build();
-  }
-
-  /**
-   * Returns an {@link dagger.model.BindingKind#OPTIONAL} binding for {@code key}.
-   *
-   * @param requestKind the kind of request for the optional binding
-   * @param underlyingKeyBindings the possibly empty set of bindings that exist in the component for
-   *     the underlying (non-optional) key
-   */
-  ContributionBinding syntheticOptionalBinding(
-      Key key, RequestKind requestKind, ResolvedBindings underlyingKeyBindings) {
-    ContributionBinding.Builder<?, ?> builder =
-        syntheticOptionalBindingBuilder(requestKind, underlyingKeyBindings)
-            .contributionType(ContributionType.UNIQUE)
-            .key(key)
-            .kind(OPTIONAL);
-    if (!underlyingKeyBindings.isEmpty()) {
-      builder.dependencies(
-          dependencyRequestFactory.forSyntheticPresentOptionalBinding(key, requestKind));
-    }
-    return builder.build();
-  }
-
-  private ContributionBinding.Builder<?, ?> syntheticOptionalBindingBuilder(
-      RequestKind requestKind, ResolvedBindings underlyingKeyBindings) {
-    return !underlyingKeyBindings.isEmpty()
-            && (underlyingKeyBindings.bindingTypes().contains(BindingType.PRODUCTION)
-                || requestKind.equals(RequestKind.PRODUCER) // handles producerFromProvider cases
-                || requestKind.equals(RequestKind.PRODUCED)) // handles producerFromProvider cases
-        ? ProductionBinding.builder()
-        : ProvisionBinding.builder();
-  }
-
-  /** Returns a {@link dagger.model.BindingKind#MEMBERS_INJECTOR} binding. */
-  ProvisionBinding membersInjectorBinding(
-      Key key, MembersInjectionBinding membersInjectionBinding) {
-    return ProvisionBinding.builder()
-        .key(key)
-        .contributionType(ContributionType.UNIQUE)
-        .kind(MEMBERS_INJECTOR)
-        .bindingElement(MoreTypes.asTypeElement(membersInjectionBinding.key().type()))
-        .provisionDependencies(membersInjectionBinding.dependencies())
-        .injectionSites(membersInjectionBinding.injectionSites())
-        .build();
-  }
-
-  /**
-   * Returns a {@link dagger.model.BindingKind#MEMBERS_INJECTION} binding.
-   *
-   * @param resolvedType if {@code declaredType} is a generic class and {@code resolvedType} is a
-   *     parameterization of that type, the returned binding will be for the resolved type
-   */
-  // TODO(dpb): See if we can just pass one nongeneric/parameterized type.
-  MembersInjectionBinding membersInjectionBinding(
-      DeclaredType declaredType, Optional<TypeMirror> resolvedType) {
-    // If the class this is injecting has some type arguments, resolve everything.
-    if (!declaredType.getTypeArguments().isEmpty() && resolvedType.isPresent()) {
-      DeclaredType resolved = asDeclared(resolvedType.get());
-      // Validate that we're resolving from the correct type.
-      checkState(
-          types.isSameType(types.erasure(resolved), types.erasure(declaredType)),
-          "erased expected type: %s, erased actual type: %s",
-          types.erasure(resolved),
-          types.erasure(declaredType));
-      declaredType = resolved;
-    }
-    ImmutableSortedSet<InjectionSite> injectionSites =
-        injectionSiteFactory.getInjectionSites(declaredType);
-    ImmutableSet<DependencyRequest> dependencies =
-        injectionSites
-            .stream()
-            .flatMap(injectionSite -> injectionSite.dependencies().stream())
-            .collect(toImmutableSet());
-
-    Key key = keyFactory.forMembersInjectedType(declaredType);
-    TypeElement typeElement = MoreElements.asType(declaredType.asElement());
-    return new AutoValue_MembersInjectionBinding(
-        key,
-        dependencies,
-        typeElement,
-        hasNonDefaultTypeParameters(typeElement, key.type(), types)
-            ? Optional.of(
-                membersInjectionBinding(asDeclared(typeElement.asType()), Optional.empty()))
-            : Optional.empty(),
-        injectionSites);
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraph.java b/java/dagger/internal/codegen/BindingGraph.java
deleted file mode 100644
index 2f548b2..0000000
--- a/java/dagger/internal/codegen/BindingGraph.java
+++ /dev/null
@@ -1,232 +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.checkState;
-import static dagger.internal.codegen.DaggerStreams.presentValues;
-import static dagger.internal.codegen.DaggerStreams.stream;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimaps;
-import com.google.common.graph.Traverser;
-import dagger.Subcomponent;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-
-/** The canonical representation of a full-resolved graph. */
-@AutoValue
-abstract class BindingGraph {
-  abstract ComponentDescriptor componentDescriptor();
-
-  /**
-   * The resolved bindings for all {@link ContributionBinding}s in this graph, keyed by {@link Key}.
-   */
-  // TODO(ronshapiro): when MembersInjectionBinding no longer extends Binding, rename this to
-  // bindings()
-  abstract ImmutableMap<Key, ResolvedBindings> contributionBindings();
-
-  /**
-   * The resolved bindings for all {@link MembersInjectionBinding}s in this graph, keyed by {@link
-   * Key}.
-   */
-  abstract ImmutableMap<Key, ResolvedBindings> membersInjectionBindings();
-
-  /**
-   * Returns the {@link ResolvedBindings resolved bindings} instance for {@code
-   * bindingExpressionKey}. If the bindings will be used for members injection, a {@link
-   * ResolvedBindings} with {@linkplain #membersInjectionBindings() members injection bindings} will
-   * be returned, otherwise a {@link ResolvedBindings} with {@link #contributionBindings()} will be
-   * returned.
-   */
-  final ResolvedBindings resolvedBindings(BindingRequest request) {
-    return request.isRequestKind(RequestKind.MEMBERS_INJECTION)
-        ? membersInjectionBindings().get(request.key())
-        : contributionBindings().get(request.key());
-  }
-
-  final Iterable<ResolvedBindings> resolvedBindings() {
-    // Don't return an immutable collection - this is only ever used for looping over all bindings
-    // in the graph. Copying is wasteful, especially if is a hashing collection, since the values
-    // should all, by definition, be distinct.
-    // TODO(dpb): consider inlining this to callers and removing this.
-    return Iterables.concat(membersInjectionBindings().values(), contributionBindings().values());
-  }
-
-  abstract ImmutableList<BindingGraph> subgraphs();
-
-  /**
-   * The type that defines the component for this graph.
-   *
-   * @see ComponentDescriptor#typeElement()
-   */
-  TypeElement componentTypeElement() {
-    return componentDescriptor().typeElement();
-  }
-
-  /**
-   * Returns the set of modules that are owned by this graph regardless of whether or not any of
-   * their bindings are used in this graph. For graphs representing top-level {@link
-   * dagger.Component components}, this set will be the same as {@linkplain
-   * ComponentDescriptor#modules() the component's transitive modules}. For {@linkplain Subcomponent
-   * subcomponents}, this set will be the transitive modules that are not owned by any of their
-   * ancestors.
-   */
-  abstract ImmutableSet<ModuleDescriptor> ownedModules();
-
-  @Memoized
-  ImmutableSet<TypeElement> ownedModuleTypes() {
-    return FluentIterable.from(ownedModules()).transform(ModuleDescriptor::moduleElement).toSet();
-  }
-
-  /**
-   * Returns the factory method for this subcomponent, if it exists.
-   *
-   * <p>This factory method is the one defined in the parent component's interface.
-   *
-   * <p>In the example below, the {@link BindingGraph#factoryMethod} for {@code ChildComponent}
-   * would return the {@link ExecutableElement}: {@code childComponent(ChildModule1)} .
-   *
-   * <pre><code>
-   *   {@literal @Component}
-   *   interface ParentComponent {
-   *     ChildComponent childComponent(ChildModule1 childModule);
-   *   }
-   * </code></pre>
-   */
-  // TODO(b/73294201): Consider returning the resolved ExecutableType for the factory method.
-  abstract Optional<ExecutableElement> factoryMethod();
-
-  /**
-   * Returns a map between the {@linkplain ComponentRequirement component requirement} and the
-   * corresponding {@link VariableElement} for each module parameter in the {@linkplain
-   * BindingGraph#factoryMethod factory method}.
-   */
-  // TODO(dpb): Consider disallowing modules if none of their bindings are used.
-  ImmutableMap<ComponentRequirement, VariableElement> factoryMethodParameters() {
-    checkState(factoryMethod().isPresent());
-    ImmutableMap.Builder<ComponentRequirement, VariableElement> builder = ImmutableMap.builder();
-    for (VariableElement parameter : factoryMethod().get().getParameters()) {
-      builder.put(ComponentRequirement.forModule(parameter.asType()), parameter);
-    }
-    return builder.build();
-  }
-
-  private static final Traverser<BindingGraph> SUBGRAPH_TRAVERSER =
-      Traverser.forTree(BindingGraph::subgraphs);
-
-  /**
-   * The types for which the component needs instances.
-   *
-   * <ul>
-   *   <li>component dependencies
-   *   <li>{@linkplain #ownedModules() owned modules} with concrete instance bindings that are used
-   *       in the graph
-   *   <li>bound instances
-   * </ul>
-   */
-  @Memoized
-  ImmutableSet<ComponentRequirement> componentRequirements() {
-    ImmutableSet<TypeElement> requiredModules = requiredModuleElements();
-    ImmutableSet.Builder<ComponentRequirement> requirements = ImmutableSet.builder();
-    componentDescriptor().requirements().stream()
-        .filter(
-            requirement ->
-                !requirement.kind().isModule()
-                    || requiredModules.contains(requirement.typeElement()))
-        .forEach(requirements::add);
-    if (factoryMethod().isPresent()) {
-      requirements.addAll(factoryMethodParameters().keySet());
-    }
-    return requirements.build();
-  }
-
-  private ImmutableSet<TypeElement> requiredModuleElements() {
-    return stream(SUBGRAPH_TRAVERSER.depthFirstPostOrder(this))
-        .flatMap(graph -> graph.contributionBindings().values().stream())
-        .flatMap(bindings -> bindings.contributionBindings().stream())
-        .map(ContributionBinding::contributingModule)
-        .distinct()
-        .flatMap(presentValues())
-        .filter(ownedModuleTypes()::contains)
-        .collect(toImmutableSet());
-  }
-
-  /** Returns the {@link ComponentDescriptor}s for this component and its subcomponents. */
-  ImmutableSet<ComponentDescriptor> componentDescriptors() {
-    return FluentIterable.from(SUBGRAPH_TRAVERSER.depthFirstPreOrder(this))
-        .transform(BindingGraph::componentDescriptor)
-        .toSet();
-  }
-
-  /**
-   * {@code true} if this graph contains all bindings installed in the component; {@code false} if
-   * it contains only those bindings that are reachable from at least one entry point.
-   */
-  abstract boolean isFullBindingGraph();
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override // Suppresses ErrorProne warning that hashCode was overridden w/o equals
-  public abstract boolean equals(Object other);
-
-  static BindingGraph create(
-      ComponentDescriptor componentDescriptor,
-      Map<Key, ResolvedBindings> resolvedContributionBindingsMap,
-      Map<Key, ResolvedBindings> resolvedMembersInjectionBindings,
-      List<BindingGraph> subgraphs,
-      Set<ModuleDescriptor> ownedModules,
-      Optional<ExecutableElement> factoryMethod,
-      boolean isFullBindingGraph) {
-    checkForDuplicates(subgraphs);
-    return new AutoValue_BindingGraph(
-        componentDescriptor,
-        ImmutableMap.copyOf(resolvedContributionBindingsMap),
-        ImmutableMap.copyOf(resolvedMembersInjectionBindings),
-        ImmutableList.copyOf(subgraphs),
-        ImmutableSet.copyOf(ownedModules),
-        factoryMethod,
-        isFullBindingGraph);
-  }
-
-  private static final void checkForDuplicates(Iterable<BindingGraph> graphs) {
-    Map<TypeElement, Collection<BindingGraph>> duplicateGraphs =
-        Maps.filterValues(
-            Multimaps.index(graphs, graph -> graph.componentDescriptor().typeElement()).asMap(),
-            overlapping -> overlapping.size() > 1);
-    if (!duplicateGraphs.isEmpty()) {
-      throw new IllegalArgumentException("Expected no duplicates: " + duplicateGraphs);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraphConverter.java b/java/dagger/internal/codegen/BindingGraphConverter.java
deleted file mode 100644
index a2cc799..0000000
--- a/java/dagger/internal/codegen/BindingGraphConverter.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2018 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.auto.common.MoreTypes.asTypeElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.DaggerGraphs.unreachableNodes;
-import static dagger.model.BindingKind.SUBCOMPONENT_CREATOR;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.graph.MutableNetwork;
-import com.google.common.graph.Network;
-import com.google.common.graph.NetworkBuilder;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.Edge;
-import dagger.model.BindingGraph.MissingBinding;
-import dagger.model.BindingGraph.Node;
-import dagger.model.BindingGraphProxies;
-import dagger.model.ComponentPath;
-import dagger.model.DependencyRequest;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/** Converts {@link dagger.internal.codegen.BindingGraph}s to {@link dagger.model.BindingGraph}s. */
-final class BindingGraphConverter {
-  private final BindingDeclarationFormatter bindingDeclarationFormatter;
-
-  @Inject
-  BindingGraphConverter(BindingDeclarationFormatter bindingDeclarationFormatter) {
-    this.bindingDeclarationFormatter = bindingDeclarationFormatter;
-  }
-
-  /**
-   * Creates the external {@link dagger.model.BindingGraph} representing the given internal {@link
-   * dagger.internal.codegen.BindingGraph}.
-   */
-  dagger.model.BindingGraph convert(BindingGraph bindingGraph) {
-    Traverser traverser = new Traverser(bindingGraph);
-    traverser.traverseComponents();
-
-    // When bindings are copied down into child graphs because they transitively depend on local
-    // multibindings or optional bindings, the parent-owned binding is still there. If that
-    // parent-owned binding is not reachable from its component, it doesn't need to be in the graph
-    // because it will never be used. So remove all nodes that are not reachable from the root
-    // component—unless we're converting a full binding graph.
-    if (!bindingGraph.isFullBindingGraph()) {
-      unreachableNodes(traverser.network.asGraph(), rootComponentNode(traverser.network))
-          .forEach(traverser.network::removeNode);
-    }
-
-    return BindingGraphProxies.bindingGraph(traverser.network, bindingGraph.isFullBindingGraph());
-  }
-
-  // TODO(dpb): Example of BindingGraph logic applied to derived networks.
-  private ComponentNode rootComponentNode(Network<Node, Edge> network) {
-    return (ComponentNode)
-        Iterables.find(
-            network.nodes(),
-            node -> node instanceof ComponentNode && node.componentPath().atRoot());
-  }
-
-  private final class Traverser extends ComponentTreeTraverser {
-    private final MutableNetwork<Node, Edge> network =
-        NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build();
-    private final boolean isRootSubcomponent;
-    private final boolean isFullBindingGraph;
-
-    private final ComponentPath rootComponentPath;
-    private ComponentNode parentComponent;
-    private ComponentNode currentComponent;
-
-    Traverser(BindingGraph graph) {
-      super(graph);
-      rootComponentPath = ComponentPath.create(ImmutableList.of(graph.componentTypeElement()));
-      isRootSubcomponent = graph.componentDescriptor().isSubcomponent();
-      isFullBindingGraph = graph.isFullBindingGraph();
-    }
-
-    @Override
-    protected void visitComponent(BindingGraph graph) {
-      ComponentNode grandparentComponent = parentComponent;
-      parentComponent = currentComponent;
-      currentComponent = ComponentNodeImpl.create(componentPath(), graph.componentDescriptor());
-
-      network.addNode(currentComponent);
-
-      for (ResolvedBindings resolvedBindings : graph.resolvedBindings()) {
-        for (BindingNode binding : bindingNodes(resolvedBindings)) {
-          addBinding(binding);
-          if (binding.kind().equals(SUBCOMPONENT_CREATOR)
-              && binding.componentPath().equals(currentComponent.componentPath())) {
-            network.addEdge(
-                binding,
-                subcomponentNode(binding.key().type(), graph),
-                new SubcomponentCreatorBindingEdgeImpl(
-                    resolvedBindings.subcomponentDeclarations()));
-          }
-        }
-      }
-
-      super.visitComponent(graph);
-
-      currentComponent = parentComponent;
-      parentComponent = grandparentComponent;
-    }
-
-    @Override
-    protected void visitEntryPoint(DependencyRequest entryPoint, BindingGraph graph) {
-      addDependencyEdges(currentComponent, entryPoint);
-      super.visitEntryPoint(entryPoint, graph);
-    }
-
-    @Override
-    protected void visitSubcomponentFactoryMethod(
-        BindingGraph graph, BindingGraph parent, ExecutableElement factoryMethod) {
-      network.addEdge(
-          parentComponent, currentComponent, new ChildFactoryMethodEdgeImpl(factoryMethod));
-      super.visitSubcomponentFactoryMethod(graph, parent, factoryMethod);
-    }
-
-    /**
-     * Adds a {@link dagger.model.BindingGraph.DependencyEdge} from a node to the binding(s) that
-     * satisfy a dependency request.
-     */
-    private void addDependencyEdges(Node source, DependencyRequest dependencyRequest) {
-      ResolvedBindings dependencies = resolvedDependencies(source, dependencyRequest);
-      if (dependencies.isEmpty()) {
-        addDependencyEdge(source, dependencyRequest, missingBindingNode(dependencies));
-      } else {
-        for (BindingNode dependency : bindingNodes(dependencies)) {
-          addDependencyEdge(source, dependencyRequest, dependency);
-        }
-      }
-    }
-
-    private void addDependencyEdge(
-        Node source, DependencyRequest dependencyRequest, Node dependency) {
-      network.addNode(dependency);
-      if (!hasDependencyEdge(source, dependency, dependencyRequest)) {
-        network.addEdge(
-            source,
-            dependency,
-            new DependencyEdgeImpl(dependencyRequest, source instanceof ComponentNode));
-      }
-    }
-
-    private boolean hasDependencyEdge(
-        Node source, Node dependency, DependencyRequest dependencyRequest) {
-      // An iterative approach is used instead of a Stream because this method is called in a hot
-      // loop, and the Stream calculates the size of network.edgesConnecting(), which is slow. This
-      // seems to be because caculating the edges connecting two nodes in a Network that supports
-      // parallel edges is must check the equality of many nodes, and BindingNode's equality
-      // semantics drag in the equality of many other expensive objects
-      for (Edge edge : network.edgesConnecting(source, dependency)) {
-        if (edge instanceof DependencyEdge) {
-          if (((DependencyEdge) edge).dependencyRequest().equals(dependencyRequest)) {
-            return true;
-          }
-        }
-      }
-      return false;
-    }
-
-    private ResolvedBindings resolvedDependencies(
-        Node source, DependencyRequest dependencyRequest) {
-      return graphForAncestor(source.componentPath().currentComponent())
-          .resolvedBindings(bindingRequest(dependencyRequest));
-    }
-
-    /** Adds a binding and all its dependencies. */
-    private void addBinding(BindingNode binding) {
-      network.addNode(binding);
-      for (DependencyRequest dependencyRequest : binding.dependencies()) {
-        addDependencyEdges(binding, dependencyRequest);
-      }
-    }
-
-    private ImmutableSet<BindingNode> bindingNodes(ResolvedBindings resolvedBindings) {
-      ImmutableSet.Builder<BindingNode> bindingNodes = ImmutableSet.builder();
-      resolvedBindings
-          .allBindings()
-          .asMap()
-          .forEach(
-              (component, bindings) -> {
-                for (Binding binding : bindings) {
-                  bindingNodes.add(bindingNode(resolvedBindings, binding, component));
-                }
-              });
-      return bindingNodes.build();
-    }
-
-    private BindingNode bindingNode(
-        ResolvedBindings resolvedBindings, Binding binding, TypeElement owningComponent) {
-      return BindingNode.create(
-          pathFromRootToAncestor(owningComponent),
-          binding,
-          resolvedBindings.multibindingDeclarations(),
-          resolvedBindings.optionalBindingDeclarations(),
-          resolvedBindings.subcomponentDeclarations(),
-          bindingDeclarationFormatter);
-    }
-
-    private MissingBinding missingBindingNode(ResolvedBindings dependencies) {
-      // TODO(b/117833324): Revisit whether limiting missing binding nodes to the root component is
-      // necessary to limit the amount of missing binding nodes in the network, or if perhaps *all*
-      // missing binding nodes should be structured this way.
-      return BindingGraphProxies.missingBindingNode(
-          isRootSubcomponent && !isFullBindingGraph ? rootComponentPath : componentPath(),
-          dependencies.key());
-    }
-
-    private ComponentNode subcomponentNode(TypeMirror subcomponentBuilderType, BindingGraph graph) {
-      TypeElement subcomponentBuilderElement = asTypeElement(subcomponentBuilderType);
-      ComponentDescriptor subcomponent =
-          graph.componentDescriptor().getChildComponentWithBuilderType(subcomponentBuilderElement);
-      return ComponentNodeImpl.create(
-          componentPath().childPath(subcomponent.typeElement()), subcomponent);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraphFactory.java b/java/dagger/internal/codegen/BindingGraphFactory.java
deleted file mode 100644
index d96da8a..0000000
--- a/java/dagger/internal/codegen/BindingGraphFactory.java
+++ /dev/null
@@ -1,1061 +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.auto.common.MoreTypes.isType;
-import static com.google.auto.common.MoreTypes.isTypeOf;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.isEmpty;
-import static dagger.internal.codegen.ComponentDescriptor.isComponentContributionMethod;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.RequestKinds.getRequestKind;
-import static dagger.internal.codegen.SourceFiles.generatedMonitoringModuleName;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.model.BindingKind.DELEGATE;
-import static dagger.model.BindingKind.INJECTION;
-import static dagger.model.BindingKind.OPTIONAL;
-import static dagger.model.BindingKind.SUBCOMPONENT_CREATOR;
-import static dagger.model.RequestKind.MEMBERS_INJECTION;
-import static java.util.function.Predicate.isEqual;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import dagger.MembersInjector;
-import dagger.Reusable;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.Scope;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.internal.ProductionExecutorModule;
-import java.util.ArrayDeque;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Queue;
-import java.util.Set;
-import java.util.function.Function;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/** A factory for {@link BindingGraph} objects. */
-@Singleton
-final class BindingGraphFactory implements ClearableCache {
-  private final DaggerElements elements;
-  private final InjectBindingRegistry injectBindingRegistry;
-  private final KeyFactory keyFactory;
-  private final BindingFactory bindingFactory;
-  private final ModuleDescriptor.Factory moduleDescriptorFactory;
-  private final Map<Key, ImmutableSet<Key>> keysMatchingRequestCache = new HashMap<>();
-
-  @Inject
-  BindingGraphFactory(
-      DaggerElements elements,
-      InjectBindingRegistry injectBindingRegistry,
-      KeyFactory keyFactory,
-      BindingFactory bindingFactory,
-      ModuleDescriptor.Factory moduleDescriptorFactory) {
-    this.elements = elements;
-    this.injectBindingRegistry = injectBindingRegistry;
-    this.keyFactory = keyFactory;
-    this.bindingFactory = bindingFactory;
-    this.moduleDescriptorFactory = moduleDescriptorFactory;
-  }
-
-  /**
-   * Creates a binding graph for a component.
-   *
-   * @param createFullBindingGraph if {@code true}, the binding graph will include all bindings;
-   *     otherwise it will include only bindings reachable from at least one entry point
-   */
-  BindingGraph create(ComponentDescriptor componentDescriptor, boolean createFullBindingGraph) {
-    return create(Optional.empty(), componentDescriptor, createFullBindingGraph);
-  }
-
-  private BindingGraph create(
-      Optional<Resolver> parentResolver,
-      ComponentDescriptor componentDescriptor,
-      boolean createFullBindingGraph) {
-    ImmutableSet.Builder<ContributionBinding> explicitBindingsBuilder = ImmutableSet.builder();
-    ImmutableSet.Builder<DelegateDeclaration> delegatesBuilder = ImmutableSet.builder();
-    ImmutableSet.Builder<OptionalBindingDeclaration> optionalsBuilder = ImmutableSet.builder();
-
-    if (componentDescriptor.isRealComponent()) {
-      // binding for the component itself
-      explicitBindingsBuilder.add(
-          bindingFactory.componentBinding(componentDescriptor.typeElement()));
-    }
-
-    // Collect Component dependencies.
-    for (ComponentRequirement dependency : componentDescriptor.dependencies()) {
-      explicitBindingsBuilder.add(bindingFactory.componentDependencyBinding(dependency));
-      List<ExecutableElement> dependencyMethods =
-          methodsIn(elements.getAllMembers(dependency.typeElement()));
-      for (ExecutableElement method : dependencyMethods) {
-        // MembersInjection methods aren't "provided" explicitly, so ignore them.
-        if (isComponentContributionMethod(elements, method)) {
-          explicitBindingsBuilder.add(
-              bindingFactory.componentDependencyMethodBinding(componentDescriptor, method));
-        }
-      }
-    }
-
-    // Collect bindings on the creator.
-    componentDescriptor
-        .creatorDescriptor()
-        .ifPresent(
-            creatorDescriptor ->
-                creatorDescriptor.boundInstanceRequirements().stream()
-                    .map(
-                        requirement ->
-                            bindingFactory.boundInstanceBinding(
-                                requirement, creatorDescriptor.elementForRequirement(requirement)))
-                    .forEach(explicitBindingsBuilder::add));
-
-    componentDescriptor
-        .childComponentsDeclaredByBuilderEntryPoints()
-        .forEach(
-            (builderEntryPoint, childComponent) -> {
-              if (!componentDescriptor
-                  .childComponentsDeclaredByModules()
-                  .contains(childComponent)) {
-                explicitBindingsBuilder.add(
-                    bindingFactory.subcomponentCreatorBinding(
-                        builderEntryPoint.methodElement(), componentDescriptor.typeElement()));
-              }
-            });
-
-    ImmutableSet.Builder<MultibindingDeclaration> multibindingDeclarations = ImmutableSet.builder();
-    ImmutableSet.Builder<SubcomponentDeclaration> subcomponentDeclarations = ImmutableSet.builder();
-
-    // Collect transitive module bindings and multibinding declarations.
-    for (ModuleDescriptor moduleDescriptor : modules(componentDescriptor, parentResolver)) {
-      explicitBindingsBuilder.addAll(moduleDescriptor.bindings());
-      multibindingDeclarations.addAll(moduleDescriptor.multibindingDeclarations());
-      subcomponentDeclarations.addAll(moduleDescriptor.subcomponentDeclarations());
-      delegatesBuilder.addAll(moduleDescriptor.delegateDeclarations());
-      optionalsBuilder.addAll(moduleDescriptor.optionalDeclarations());
-    }
-
-    final Resolver requestResolver =
-        new Resolver(
-            parentResolver,
-            componentDescriptor,
-            indexBindingDeclarationsByKey(explicitBindingsBuilder.build()),
-            indexBindingDeclarationsByKey(multibindingDeclarations.build()),
-            indexBindingDeclarationsByKey(subcomponentDeclarations.build()),
-            indexBindingDeclarationsByKey(delegatesBuilder.build()),
-            indexBindingDeclarationsByKey(optionalsBuilder.build()));
-
-    componentDescriptor.entryPointMethods().stream()
-        .map(method -> method.dependencyRequest().get())
-        .forEach(
-            entryPoint -> {
-              if (entryPoint.kind().equals(MEMBERS_INJECTION)) {
-                requestResolver.resolveMembersInjection(entryPoint.key());
-              } else {
-                requestResolver.resolve(entryPoint.key());
-              }
-            });
-
-    if (createFullBindingGraph) {
-      // Resolve the keys for all bindings in all modules, stripping any multibinding contribution
-      // identifier so that the multibinding itself is resolved.
-      modules(componentDescriptor, parentResolver).stream()
-          .flatMap(module -> module.allBindingKeys().stream())
-          .map(key -> key.toBuilder().multibindingContributionIdentifier(Optional.empty()).build())
-          .forEach(requestResolver::resolve);
-    }
-
-    // Resolve all bindings for subcomponents, creating subgraphs for all subcomponents that have
-    // been detected during binding resolution. If a binding for a subcomponent is never resolved,
-    // no BindingGraph will be created for it and no implementation will be generated. This is
-    // done in a queue since resolving one subcomponent might resolve a key for a subcomponent
-    // from a parent graph. This is done until no more new subcomponents are resolved.
-    Set<ComponentDescriptor> resolvedSubcomponents = new HashSet<>();
-    ImmutableList.Builder<BindingGraph> subgraphs = ImmutableList.builder();
-    for (ComponentDescriptor subcomponent :
-        Iterables.consumingIterable(requestResolver.subcomponentsToResolve)) {
-      if (resolvedSubcomponents.add(subcomponent)) {
-        subgraphs.add(create(Optional.of(requestResolver), subcomponent, createFullBindingGraph));
-      }
-    }
-
-    return BindingGraph.create(
-        componentDescriptor,
-        requestResolver.getResolvedContributionBindings(),
-        requestResolver.getResolvedMembersInjectionBindings(),
-        subgraphs.build(),
-        requestResolver.getOwnedModules(),
-        requestResolver.getFactoryMethod(),
-        createFullBindingGraph);
-  }
-
-  /**
-   * Returns all the modules that should be installed in the component. For production components
-   * and production subcomponents that have a parent that is not a production component or
-   * subcomponent, also includes the production monitoring module for the component and the
-   * production executor module.
-   */
-  private ImmutableSet<ModuleDescriptor> modules(
-      ComponentDescriptor componentDescriptor, Optional<Resolver> parentResolver) {
-    return shouldIncludeImplicitProductionModules(componentDescriptor, parentResolver)
-        ? new ImmutableSet.Builder<ModuleDescriptor>()
-            .addAll(componentDescriptor.modules())
-            .add(descriptorForMonitoringModule(componentDescriptor.typeElement()))
-            .add(descriptorForProductionExecutorModule())
-            .build()
-        : componentDescriptor.modules();
-  }
-
-  private boolean shouldIncludeImplicitProductionModules(
-      ComponentDescriptor component, Optional<Resolver> parentResolver) {
-    return component.isProduction()
-        && ((!component.isSubcomponent() && component.isRealComponent())
-            || (parentResolver.isPresent()
-                && !parentResolver.get().componentDescriptor.isProduction()));
-  }
-
-  /**
-   * Returns a descriptor for a generated module that handles monitoring for production components.
-   * This module is generated in the {@link MonitoringModuleProcessingStep}.
-   *
-   * @throws TypeNotPresentException if the module has not been generated yet. This will cause the
-   *     processor to retry in a later processing round.
-   */
-  private ModuleDescriptor descriptorForMonitoringModule(TypeElement componentDefinitionType) {
-    return moduleDescriptorFactory.create(
-        elements.checkTypePresent(
-            generatedMonitoringModuleName(componentDefinitionType).toString()));
-  }
-
-  /** Returns a descriptor {@link ProductionExecutorModule}. */
-  private ModuleDescriptor descriptorForProductionExecutorModule() {
-    return moduleDescriptorFactory.create(elements.getTypeElement(ProductionExecutorModule.class));
-  }
-
-  /** Indexes {@code bindingDeclarations} by {@link BindingDeclaration#key()}. */
-  private static <T extends BindingDeclaration>
-      ImmutableSetMultimap<Key, T> indexBindingDeclarationsByKey(Iterable<T> declarations) {
-    return ImmutableSetMultimap.copyOf(Multimaps.index(declarations, BindingDeclaration::key));
-  }
-
-  @Override
-  public void clearCache() {
-    keysMatchingRequestCache.clear();
-  }
-
-  private final class Resolver {
-    final Optional<Resolver> parentResolver;
-    final ComponentDescriptor componentDescriptor;
-    final ImmutableSetMultimap<Key, ContributionBinding> explicitBindings;
-    final ImmutableSet<ContributionBinding> explicitBindingsSet;
-    final ImmutableSetMultimap<Key, ContributionBinding> explicitMultibindings;
-    final ImmutableSetMultimap<Key, MultibindingDeclaration> multibindingDeclarations;
-    final ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations;
-    final ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations;
-    final ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations;
-    final ImmutableSetMultimap<Key, DelegateDeclaration> delegateMultibindingDeclarations;
-    final Map<Key, ResolvedBindings> resolvedContributionBindings = new LinkedHashMap<>();
-    final Map<Key, ResolvedBindings> resolvedMembersInjectionBindings = new LinkedHashMap<>();
-    final Deque<Key> cycleStack = new ArrayDeque<>();
-    final Map<Key, Boolean> keyDependsOnLocalBindingsCache = new HashMap<>();
-    final Map<Binding, Boolean> bindingDependsOnLocalBindingsCache = new HashMap<>();
-    final Queue<ComponentDescriptor> subcomponentsToResolve = new ArrayDeque<>();
-
-    Resolver(
-        Optional<Resolver> parentResolver,
-        ComponentDescriptor componentDescriptor,
-        ImmutableSetMultimap<Key, ContributionBinding> explicitBindings,
-        ImmutableSetMultimap<Key, MultibindingDeclaration> multibindingDeclarations,
-        ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations,
-        ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations,
-        ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations) {
-      this.parentResolver = parentResolver;
-      this.componentDescriptor = checkNotNull(componentDescriptor);
-      this.explicitBindings = checkNotNull(explicitBindings);
-      this.explicitBindingsSet = ImmutableSet.copyOf(explicitBindings.values());
-      this.multibindingDeclarations = checkNotNull(multibindingDeclarations);
-      this.subcomponentDeclarations = checkNotNull(subcomponentDeclarations);
-      this.delegateDeclarations = checkNotNull(delegateDeclarations);
-      this.optionalBindingDeclarations = checkNotNull(optionalBindingDeclarations);
-      this.explicitMultibindings = multibindingContributionsByMultibindingKey(explicitBindingsSet);
-      this.delegateMultibindingDeclarations =
-          multibindingContributionsByMultibindingKey(delegateDeclarations.values());
-      subcomponentsToResolve.addAll(
-          componentDescriptor.childComponentsDeclaredByFactoryMethods().values());
-      subcomponentsToResolve.addAll(
-          componentDescriptor.childComponentsDeclaredByBuilderEntryPoints().values());
-    }
-
-    /** Returns the optional factory method for this component. */
-    Optional<ExecutableElement> getFactoryMethod() {
-      return parentResolver
-          .flatMap(
-              parent ->
-                  parent.componentDescriptor.getFactoryMethodForChildComponent(componentDescriptor))
-          .map(method -> method.methodElement());
-    }
-
-    /**
-     * Returns the resolved contribution bindings for the given {@link Key}:
-     *
-     * <ul>
-     *   <li>All explicit bindings for:
-     *       <ul>
-     *         <li>the requested key
-     *         <li>{@code Set<T>} if the requested key's type is {@code Set<Produced<T>>}
-     *         <li>{@code Map<K, Provider<V>>} if the requested key's type is {@code Map<K,
-     *             Producer<V>>}.
-     *       </ul>
-     *   <li>A synthetic binding that depends on {@code Map<K, Producer<V>>} if the requested key's
-     *       type is {@code Map<K, V>} and there are some explicit bindings for {@code Map<K,
-     *       Producer<V>>}.
-     *   <li>A synthetic binding that depends on {@code Map<K, Provider<V>>} if the requested key's
-     *       type is {@code Map<K, V>} and there are some explicit bindings for {@code Map<K,
-     *       Provider<V>>} but no explicit bindings for {@code Map<K, Producer<V>>}.
-     *   <li>An implicit {@link Inject @Inject}-annotated constructor binding if there is one and
-     *       there are no explicit bindings or synthetic bindings.
-     * </ul>
-     */
-    ResolvedBindings lookUpBindings(Key requestKey) {
-      Set<ContributionBinding> bindings = new LinkedHashSet<>();
-      bindings.addAll(getExplicitBindings(requestKey));
-
-      ImmutableSet<ContributionBinding> multibindingContributions =
-          getAllMatchingBindingDeclarations(requestKey, this::getExplicitMultibindings);
-      ImmutableSet<MultibindingDeclaration> multibindingDeclarations =
-          getAllMatchingBindingDeclarations(requestKey, this::getMultibindingDeclarations);
-
-      syntheticMultibinding(requestKey, multibindingContributions, multibindingDeclarations)
-          .ifPresent(bindings::add);
-
-      ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations =
-          getAllMatchingBindingDeclarations(requestKey, this::getOptionalBindingDeclarations);
-      syntheticOptionalBinding(requestKey, optionalBindingDeclarations).ifPresent(bindings::add);
-
-      ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations =
-          getSubcomponentDeclarations(requestKey);
-      syntheticSubcomponentBuilderBinding(subcomponentDeclarations)
-          .ifPresent(
-              binding -> {
-                bindings.add(binding);
-                addSubcomponentToOwningResolver(binding);
-              });
-
-      if (isType(requestKey.type()) && isTypeOf(MembersInjector.class, requestKey.type())) {
-        injectBindingRegistry
-            .getOrFindMembersInjectorProvisionBinding(requestKey)
-            .ifPresent(bindings::add);
-      }
-
-      // If there are no bindings, add the implicit @Inject-constructed binding if there is one.
-      if (bindings.isEmpty()) {
-        injectBindingRegistry.getOrFindProvisionBinding(requestKey)
-            .filter(binding -> !isIncorrectlyScopedInPartialGraph(binding))
-            .ifPresent(bindings::add);
-      }
-
-      return ResolvedBindings.forContributionBindings(
-          requestKey,
-          indexBindingsByOwningComponent(requestKey, ImmutableSet.copyOf(bindings)),
-          multibindingDeclarations,
-          subcomponentDeclarations,
-          optionalBindingDeclarations);
-    }
-
-    /**
-     * Returns true if this binding graph resolution is for a partial graph and the {@code @Inject}
-     * binding's scope doesn't match any of the components in the current component ancestry. If so,
-     * the binding is not owned by any of the currently known components, and will be owned by a
-     * future ancestor (or, if never owned, will result in an incompatibly scoped binding error at
-     * the root component).
-     */
-    private boolean isIncorrectlyScopedInPartialGraph(ProvisionBinding binding) {
-      checkArgument(binding.kind().equals(INJECTION));
-      Resolver owningResolver = getOwningResolver(binding).orElse(this);
-      ComponentDescriptor owningComponent = owningResolver.componentDescriptor;
-      return rootComponent().isSubcomponent()
-          && binding.scope().isPresent()
-          && !binding.scope().get().isReusable()
-          && !owningComponent.scopes().contains(binding.scope().get());
-    }
-
-    private ComponentDescriptor rootComponent() {
-      return parentResolver.map(Resolver::rootComponent).orElse(componentDescriptor);
-    }
-
-    /** Returns the resolved members injection bindings for the given {@link Key}. */
-    ResolvedBindings lookUpMembersInjectionBinding(Key requestKey) {
-      // no explicit deps for members injection, so just look it up
-      Optional<MembersInjectionBinding> binding =
-          injectBindingRegistry.getOrFindMembersInjectionBinding(requestKey);
-      return binding.isPresent()
-          ? ResolvedBindings.forMembersInjectionBinding(
-              requestKey, componentDescriptor, binding.get())
-          : ResolvedBindings.noBindings(requestKey);
-    }
-
-    /**
-     * When a binding is resolved for a {@link SubcomponentDeclaration}, adds corresponding {@link
-     * ComponentDescriptor subcomponent} to a queue in the owning component's resolver. The queue
-     * will be used to detect which subcomponents need to be resolved.
-     */
-    private void addSubcomponentToOwningResolver(ProvisionBinding subcomponentCreatorBinding) {
-      checkArgument(subcomponentCreatorBinding.kind().equals(SUBCOMPONENT_CREATOR));
-      Resolver owningResolver = getOwningResolver(subcomponentCreatorBinding).get();
-
-      TypeElement builderType = MoreTypes.asTypeElement(subcomponentCreatorBinding.key().type());
-      owningResolver.subcomponentsToResolve.add(
-          owningResolver.componentDescriptor.getChildComponentWithBuilderType(builderType));
-    }
-
-    /**
-     * Profiling has determined that computing the keys matching {@code requestKey} has measurable
-     * performance impact. It is called repeatedly (at least 3 times per key resolved per {@link
-     * BindingGraph}. {@code javac}'s name-checking performance seems suboptimal (converting byte
-     * strings to Strings repeatedly), and the matching keys creations relies on that. This also
-     * ensures that the resulting keys have their hash codes cached on successive calls to this
-     * method.
-     *
-     * <p>This caching may become obsolete if:
-     *
-     * <ul>
-     *   <li>We decide to intern all {@link Key} instances
-     *   <li>We fix javac's name-checking peformance (though we may want to keep this for older
-     *       javac users)
-     * </ul>
-     */
-    private ImmutableSet<Key> keysMatchingRequest(Key requestKey) {
-      return keysMatchingRequestCache.computeIfAbsent(
-          requestKey, this::keysMatchingRequestUncached);
-    }
-
-    private ImmutableSet<Key> keysMatchingRequestUncached(Key requestKey) {
-      ImmutableSet.Builder<Key> keys = ImmutableSet.builder();
-      keys.add(requestKey);
-      keyFactory.unwrapSetKey(requestKey, Produced.class).ifPresent(keys::add);
-      keyFactory.rewrapMapKey(requestKey, Producer.class, Provider.class).ifPresent(keys::add);
-      keyFactory.rewrapMapKey(requestKey, Provider.class, Producer.class).ifPresent(keys::add);
-      keys.addAll(keyFactory.implicitFrameworkMapKeys(requestKey));
-      return keys.build();
-    }
-
-    /**
-     * Returns a synthetic binding that depends on individual multibinding contributions.
-     *
-     * <p>If there are no {@code multibindingContributions} or {@code multibindingDeclarations},
-     * returns {@link Optional#empty()}.
-     *
-     * <p>If there are production {@code multibindingContributions} or the request is for any of the
-     * following types, returns a {@link ProductionBinding}.
-     *
-     * <ul>
-     *   <li>{@code Set<Produced<T>>}
-     *   <li>{@code Map<K, Producer<V>>}
-     *   <li>{@code Map<K, Produced<V>>}
-     * </ul>
-     *
-     * Otherwise, returns a {@link ProvisionBinding}.
-     */
-    private Optional<ContributionBinding> syntheticMultibinding(
-        Key key,
-        Iterable<ContributionBinding> multibindingContributions,
-        Iterable<MultibindingDeclaration> multibindingDeclarations) {
-      return isEmpty(multibindingContributions) && isEmpty(multibindingDeclarations)
-          ? Optional.empty()
-          : Optional.of(bindingFactory.syntheticMultibinding(key, multibindingContributions));
-    }
-
-    private Optional<ProvisionBinding> syntheticSubcomponentBuilderBinding(
-        ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) {
-      return subcomponentDeclarations.isEmpty()
-          ? Optional.empty()
-          : Optional.of(bindingFactory.subcomponentCreatorBinding(subcomponentDeclarations));
-    }
-
-    /**
-     * Returns a synthetic binding for {@code @Qualifier Optional<Type>} if there are any {@code
-     * optionalBindingDeclarations}.
-     *
-     * <p>If there are no bindings for the underlying key (the key for dependency requests for
-     * {@code Type}), returns a provision binding that always returns {@link Optional#empty()}.
-     *
-     * <p>If there are any production bindings for the underlying key, returns a production binding.
-     * Otherwise returns a provision binding.
-     */
-    private Optional<ContributionBinding> syntheticOptionalBinding(
-        Key key, ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations) {
-      return optionalBindingDeclarations.isEmpty()
-          ? Optional.empty()
-          : Optional.of(
-              bindingFactory.syntheticOptionalBinding(
-                  key,
-                  getRequestKind(OptionalType.from(key).valueType()),
-                  lookUpBindings(keyFactory.unwrapOptional(key).get())));
-    }
-
-    private ImmutableSet<ContributionBinding> createDelegateBindings(
-        ImmutableSet<DelegateDeclaration> delegateDeclarations) {
-      ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder();
-      for (DelegateDeclaration delegateDeclaration : delegateDeclarations) {
-        builder.add(createDelegateBinding(delegateDeclaration));
-      }
-      return builder.build();
-    }
-
-    /**
-     * Creates one (and only one) delegate binding for a delegate declaration, based on the resolved
-     * bindings of the right-hand-side of a {@link dagger.Binds} method. If there are duplicate
-     * bindings for the dependency key, there should still be only one binding for the delegate key.
-     */
-    private ContributionBinding createDelegateBinding(DelegateDeclaration delegateDeclaration) {
-      Key delegateKey = delegateDeclaration.delegateRequest().key();
-      if (cycleStack.contains(delegateKey)) {
-        return bindingFactory.unresolvedDelegateBinding(delegateDeclaration);
-      }
-
-      ResolvedBindings resolvedDelegate;
-      try {
-        cycleStack.push(delegateKey);
-        resolvedDelegate = lookUpBindings(delegateKey);
-      } finally {
-        cycleStack.pop();
-      }
-      if (resolvedDelegate.contributionBindings().isEmpty()) {
-        // This is guaranteed to result in a missing binding error, so it doesn't matter if the
-        // binding is a Provision or Production, except if it is a @IntoMap method, in which
-        // case the key will be of type Map<K, Provider<V>>, which will be "upgraded" into a
-        // Map<K, Producer<V>> if it's requested in a ProductionComponent. This may result in a
-        // strange error, that the RHS needs to be provided with an @Inject or @Provides
-        // annotated method, but a user should be able to figure out if a @Produces annotation
-        // is needed.
-        // TODO(gak): revisit how we model missing delegates if/when we clean up how we model
-        // binding declarations
-        return bindingFactory.unresolvedDelegateBinding(delegateDeclaration);
-      }
-      // It doesn't matter which of these is selected, since they will later on produce a
-      // duplicate binding error.
-      ContributionBinding explicitDelegate =
-          resolvedDelegate.contributionBindings().iterator().next();
-      return bindingFactory.delegateBinding(delegateDeclaration, explicitDelegate);
-    }
-
-    // TODO(dpb,ronshapiro): requestKey appears to be interchangeable with each binding's .key(),
-    // but should it? We're currently conflating the two all over the place and it would be good
-    // to unify, or if it's necessary, clarify why with docs+tests. Specifically, should we also
-    // be checking these for keysMatchingRequest?
-    private ImmutableSetMultimap<TypeElement, ContributionBinding> indexBindingsByOwningComponent(
-        Key requestKey, Iterable<? extends ContributionBinding> bindings) {
-      ImmutableSetMultimap.Builder<TypeElement, ContributionBinding> index =
-          ImmutableSetMultimap.builder();
-      for (ContributionBinding binding : bindings) {
-        index.put(getOwningComponent(requestKey, binding), binding);
-      }
-      return index.build();
-    }
-
-    /**
-     * Returns the component that should contain the framework field for {@code binding}.
-     *
-     * <p>If {@code binding} is either not bound in an ancestor component or depends transitively on
-     * bindings in this component, returns this component.
-     *
-     * <p>Otherwise, resolves {@code request} in this component's parent in order to resolve any
-     * multibinding contributions in the parent, and returns the parent-resolved {@link
-     * ResolvedBindings#owningComponent(ContributionBinding)}.
-     */
-    private TypeElement getOwningComponent(Key requestKey, ContributionBinding binding) {
-      if (isResolvedInParent(requestKey, binding)
-          && !new LocalDependencyChecker().dependsOnLocalBindings(binding)) {
-        ResolvedBindings parentResolvedBindings =
-            parentResolver.get().resolvedContributionBindings.get(requestKey);
-        return parentResolvedBindings.owningComponent(binding);
-      } else {
-        return componentDescriptor.typeElement();
-      }
-    }
-
-    /**
-     * Returns {@code true} if {@code binding} is owned by an ancestor. If so, {@linkplain #resolve
-     * resolves} the {@link Key} in this component's parent. Don't resolve directly in the owning
-     * component in case it depends on multibindings in any of its descendants.
-     */
-    private boolean isResolvedInParent(Key requestKey, ContributionBinding binding) {
-      Optional<Resolver> owningResolver = getOwningResolver(binding);
-      if (owningResolver.isPresent() && !owningResolver.get().equals(this)) {
-        parentResolver.get().resolve(requestKey);
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    private Optional<Resolver> getOwningResolver(ContributionBinding binding) {
-      // TODO(ronshapiro): extract the different pieces of this method into their own methods
-      if ((binding.scope().isPresent() && binding.scope().get().isProductionScope())
-          || binding.bindingType().equals(BindingType.PRODUCTION)) {
-        for (Resolver requestResolver : getResolverLineage()) {
-          // Resolve @Inject @ProductionScope bindings at the highest production component.
-          if (binding.kind().equals(INJECTION)
-              && requestResolver.componentDescriptor.isProduction()) {
-            return Optional.of(requestResolver);
-          }
-
-          // Resolve explicit @Produces and @ProductionScope bindings at the highest component that
-          // installs the binding.
-          if (requestResolver.containsExplicitBinding(binding)) {
-            return Optional.of(requestResolver);
-          }
-        }
-      }
-
-      if (binding.scope().isPresent() && binding.scope().get().isReusable()) {
-        for (Resolver requestResolver : getResolverLineage().reverse()) {
-          // If a @Reusable binding was resolved in an ancestor, use that component.
-          ResolvedBindings resolvedBindings =
-              requestResolver.resolvedContributionBindings.get(binding.key());
-          if (resolvedBindings != null
-              && resolvedBindings.contributionBindings().contains(binding)) {
-            return Optional.of(requestResolver);
-          }
-        }
-        // If a @Reusable binding was not resolved in any ancestor, resolve it here.
-        return Optional.empty();
-      }
-
-      for (Resolver requestResolver : getResolverLineage().reverse()) {
-        if (requestResolver.containsExplicitBinding(binding)) {
-          return Optional.of(requestResolver);
-        }
-      }
-
-      // look for scope separately.  we do this for the case where @Singleton can appear twice
-      // in the † compatibility mode
-      Optional<Scope> bindingScope = binding.scope();
-      if (bindingScope.isPresent()) {
-        for (Resolver requestResolver : getResolverLineage().reverse()) {
-          if (requestResolver.componentDescriptor.scopes().contains(bindingScope.get())) {
-            return Optional.of(requestResolver);
-          }
-        }
-      }
-      return Optional.empty();
-    }
-
-    private boolean containsExplicitBinding(ContributionBinding binding) {
-      return explicitBindingsSet.contains(binding)
-          || resolverContainsDelegateDeclarationForBinding(binding)
-          || subcomponentDeclarations.containsKey(binding.key());
-    }
-
-    /** Returns true if {@code binding} was installed in a module in this resolver's component. */
-    private boolean resolverContainsDelegateDeclarationForBinding(ContributionBinding binding) {
-      return binding.kind().equals(DELEGATE)
-          && delegateDeclarations.get(binding.key()).stream()
-              .anyMatch(
-                  declaration ->
-                      declaration.contributingModule().equals(binding.contributingModule())
-                          && declaration.bindingElement().equals(binding.bindingElement()));
-    }
-
-    /** Returns the resolver lineage from parent to child. */
-    private ImmutableList<Resolver> getResolverLineage() {
-      ImmutableList.Builder<Resolver> resolverList = ImmutableList.builder();
-      for (Optional<Resolver> currentResolver = Optional.of(this);
-          currentResolver.isPresent();
-          currentResolver = currentResolver.get().parentResolver) {
-        resolverList.add(currentResolver.get());
-      }
-      return resolverList.build().reverse();
-    }
-
-    /**
-     * For all {@linkplain #keysMatchingRequest(Key) keys matching {@code requestKey}}, applies
-     * {@code getDeclarationsPerKey} and collects the values into an {@link ImmutableSet}.
-     */
-    private <T extends BindingDeclaration> ImmutableSet<T> getAllMatchingBindingDeclarations(
-        Key requestKey, Function<Key, Collection<T>> getDeclarationsPerKey) {
-      return keysMatchingRequest(requestKey)
-          .stream()
-          .flatMap(key -> getDeclarationsPerKey.apply(key).stream())
-          .collect(toImmutableSet());
-    }
-
-    /**
-     * Returns the explicit {@link ContributionBinding}s that match the {@code key} from this and
-     * all ancestor resolvers.
-     */
-    private ImmutableSet<ContributionBinding> getExplicitBindings(Key key) {
-      ImmutableSet.Builder<ContributionBinding> bindings = ImmutableSet.builder();
-      for (Resolver resolver : getResolverLineage()) {
-        bindings.addAll(resolver.getLocalExplicitBindings(key));
-      }
-      return bindings.build();
-    }
-
-    /**
-     * Returns the explicit {@link ContributionBinding}s that match the {@code key} from this
-     * resolver.
-     */
-    private ImmutableSet<ContributionBinding> getLocalExplicitBindings(Key key) {
-      return new ImmutableSet.Builder<ContributionBinding>()
-          .addAll(explicitBindings.get(key))
-          // @Binds @IntoMap declarations have key Map<K, V>, unlike @Provides @IntoMap or @Produces
-          // @IntoMap, which have Map<K, Provider/Producer<V>> keys. So unwrap the key's type's
-          // value type if it's a Map<K, Provider/Producer<V>> before looking in
-          // delegateDeclarations. createDelegateBindings() will create bindings with the properly
-          // wrapped key type.
-          .addAll(
-              createDelegateBindings(delegateDeclarations.get(keyFactory.unwrapMapValueType(key))))
-          .build();
-    }
-
-    /**
-     * Returns the explicit multibinding contributions that contribute to the map or set requested
-     * by {@code key} from this and all ancestor resolvers.
-     */
-    private ImmutableSet<ContributionBinding> getExplicitMultibindings(Key key) {
-      ImmutableSet.Builder<ContributionBinding> multibindings = ImmutableSet.builder();
-      for (Resolver resolver : getResolverLineage()) {
-        multibindings.addAll(resolver.getLocalExplicitMultibindings(key));
-      }
-      return multibindings.build();
-    }
-
-    /**
-     * Returns the explicit multibinding contributions that contribute to the map or set requested
-     * by {@code key} from this resolver.
-     */
-    private ImmutableSet<ContributionBinding> getLocalExplicitMultibindings(Key key) {
-      ImmutableSet.Builder<ContributionBinding> multibindings = ImmutableSet.builder();
-      multibindings.addAll(explicitMultibindings.get(key));
-      if (!MapType.isMap(key)
-          || MapType.from(key).isRawType()
-          || MapType.from(key).valuesAreFrameworkType()) {
-        // @Binds @IntoMap declarations have key Map<K, V>, unlike @Provides @IntoMap or @Produces
-        // @IntoMap, which have Map<K, Provider/Producer<V>> keys. So unwrap the key's type's
-        // value type if it's a Map<K, Provider/Producer<V>> before looking in
-        // delegateMultibindingDeclarations. createDelegateBindings() will create bindings with the
-        // properly wrapped key type.
-        multibindings.addAll(
-            createDelegateBindings(
-                delegateMultibindingDeclarations.get(keyFactory.unwrapMapValueType(key))));
-      }
-      return multibindings.build();
-    }
-
-    /**
-     * Returns the {@link MultibindingDeclaration}s that match the {@code key} from this and all
-     * ancestor resolvers.
-     */
-    private ImmutableSet<MultibindingDeclaration> getMultibindingDeclarations(Key key) {
-      ImmutableSet.Builder<MultibindingDeclaration> multibindingDeclarations =
-          ImmutableSet.builder();
-      for (Resolver resolver : getResolverLineage()) {
-        multibindingDeclarations.addAll(resolver.multibindingDeclarations.get(key));
-      }
-      return multibindingDeclarations.build();
-    }
-
-    /**
-     * Returns the {@link SubcomponentDeclaration}s that match the {@code key} from this and all
-     * ancestor resolvers.
-     */
-    private ImmutableSet<SubcomponentDeclaration> getSubcomponentDeclarations(Key key) {
-      ImmutableSet.Builder<SubcomponentDeclaration> subcomponentDeclarations =
-          ImmutableSet.builder();
-      for (Resolver resolver : getResolverLineage()) {
-        subcomponentDeclarations.addAll(resolver.subcomponentDeclarations.get(key));
-      }
-      return subcomponentDeclarations.build();
-    }
-    /**
-     * Returns the {@link OptionalBindingDeclaration}s that match the {@code key} from this and all
-     * ancestor resolvers.
-     */
-    private ImmutableSet<OptionalBindingDeclaration> getOptionalBindingDeclarations(Key key) {
-      Optional<Key> unwrapped = keyFactory.unwrapOptional(key);
-      if (!unwrapped.isPresent()) {
-        return ImmutableSet.of();
-      }
-      ImmutableSet.Builder<OptionalBindingDeclaration> declarations = ImmutableSet.builder();
-      for (Resolver resolver : getResolverLineage()) {
-        declarations.addAll(resolver.optionalBindingDeclarations.get(unwrapped.get()));
-      }
-      return declarations.build();
-    }
-
-    /**
-     * Returns the {@link ResolvedBindings} for {@code key} that was resolved in this resolver or an
-     * ancestor resolver. Only checks for {@link ContributionBinding}s as {@link
-     * MembersInjectionBinding}s are not inherited.
-     */
-    private Optional<ResolvedBindings> getPreviouslyResolvedBindings(Key key) {
-      Optional<ResolvedBindings> result =
-          Optional.ofNullable(resolvedContributionBindings.get(key));
-      if (result.isPresent()) {
-        return result;
-      } else if (parentResolver.isPresent()) {
-        return parentResolver.get().getPreviouslyResolvedBindings(key);
-      } else {
-        return Optional.empty();
-      }
-    }
-
-    private void resolveMembersInjection(Key key) {
-      ResolvedBindings bindings = lookUpMembersInjectionBinding(key);
-      resolveDependencies(bindings);
-      resolvedMembersInjectionBindings.put(key, bindings);
-    }
-
-    void resolve(Key key) {
-      // If we find a cycle, stop resolving. The original request will add it with all of the
-      // other resolved deps.
-      if (cycleStack.contains(key)) {
-        return;
-      }
-
-      // If the binding was previously resolved in this (sub)component, don't resolve it again.
-      if (resolvedContributionBindings.containsKey(key)) {
-        return;
-      }
-
-      /*
-       * If the binding was previously resolved in an ancestor component, then we may be able to
-       * avoid resolving it here and just depend on the ancestor component resolution.
-       *
-       * 1. If it depends transitively on multibinding contributions or optional bindings with
-       *    bindings from this subcomponent, then we have to resolve it in this subcomponent so
-       *    that it sees the local bindings.
-       *
-       * 2. If there are any explicit bindings in this component, they may conflict with those in
-       *    the ancestor component, so resolve them here so that conflicts can be caught.
-       */
-      if (getPreviouslyResolvedBindings(key).isPresent()) {
-        /* Resolve in the parent in case there are multibinding contributions or conflicts in some
-         * component between this one and the previously-resolved one. */
-        parentResolver.get().resolve(key);
-        if (!new LocalDependencyChecker().dependsOnLocalBindings(key)
-            && getLocalExplicitBindings(key).isEmpty()) {
-          /* Cache the inherited parent component's bindings in case resolving at the parent found
-           * bindings in some component between this one and the previously-resolved one. */
-          resolvedContributionBindings.put(key, getPreviouslyResolvedBindings(key).get());
-          return;
-        }
-      }
-
-      cycleStack.push(key);
-      try {
-        ResolvedBindings bindings = lookUpBindings(key);
-        resolvedContributionBindings.put(key, bindings);
-        resolveDependencies(bindings);
-      } finally {
-        cycleStack.pop();
-      }
-    }
-
-    /**
-     * {@link #resolve(Key) Resolves} each of the dependencies of the bindings owned by this
-     * component.
-     */
-    private void resolveDependencies(ResolvedBindings resolvedBindings) {
-      for (Binding binding : resolvedBindings.bindingsOwnedBy(componentDescriptor)) {
-        for (DependencyRequest dependency : binding.dependencies()) {
-          resolve(dependency.key());
-        }
-      }
-    }
-
-    /**
-     * Returns all of the {@link ResolvedBindings} for {@link ContributionBinding}s from this and
-     * all ancestor resolvers, indexed by {@link ResolvedBindings#key()}.
-     */
-    Map<Key, ResolvedBindings> getResolvedContributionBindings() {
-      Map<Key, ResolvedBindings> bindings = new LinkedHashMap<>();
-      parentResolver.ifPresent(parent -> bindings.putAll(parent.getResolvedContributionBindings()));
-      bindings.putAll(resolvedContributionBindings);
-      return bindings;
-    }
-
-    /**
-     * Returns all of the {@link ResolvedBindings} for {@link MembersInjectionBinding} from this
-     * resolvers, indexed by {@link ResolvedBindings#key()}.
-     */
-    ImmutableMap<Key, ResolvedBindings> getResolvedMembersInjectionBindings() {
-      return ImmutableMap.copyOf(resolvedMembersInjectionBindings);
-    }
-
-    ImmutableSet<ModuleDescriptor> getInheritedModules() {
-      return parentResolver.isPresent()
-          ? Sets.union(
-                  parentResolver.get().getInheritedModules(),
-                  parentResolver.get().componentDescriptor.modules())
-              .immutableCopy()
-          : ImmutableSet.<ModuleDescriptor>of();
-    }
-
-    ImmutableSet<ModuleDescriptor> getOwnedModules() {
-      return Sets.difference(componentDescriptor.modules(), getInheritedModules()).immutableCopy();
-    }
-
-    private final class LocalDependencyChecker {
-      private final Set<Object> cycleChecker = new HashSet<>();
-
-      /**
-       * Returns {@code true} if any of the bindings resolved for {@code key} are multibindings with
-       * contributions declared within this component's modules or optional bindings with present
-       * values declared within this component's modules, or if any of its unscoped dependencies
-       * depend on such bindings.
-       *
-       * <p>We don't care about scoped dependencies because they will never depend on bindings from
-       * subcomponents.
-       *
-       * @throws IllegalArgumentException if {@link #getPreviouslyResolvedBindings(Key)} is empty
-       */
-      boolean dependsOnLocalBindings(Key key) {
-        // Don't recur infinitely if there are valid cycles in the dependency graph.
-        // http://b/23032377
-        if (!cycleChecker.add(key)) {
-          return false;
-        }
-        return reentrantComputeIfAbsent(
-            keyDependsOnLocalBindingsCache, key, this::dependsOnLocalBindingsUncached);
-      }
-
-      private boolean dependsOnLocalBindingsUncached(Key key) {
-        checkArgument(
-            getPreviouslyResolvedBindings(key).isPresent(),
-            "no previously resolved bindings in %s for %s",
-            Resolver.this,
-            key);
-        ResolvedBindings previouslyResolvedBindings = getPreviouslyResolvedBindings(key).get();
-        if (hasLocalMultibindingContributions(key)
-            || hasLocalOptionalBindingContribution(previouslyResolvedBindings)) {
-          return true;
-        }
-
-        for (Binding binding : previouslyResolvedBindings.bindings()) {
-          if (dependsOnLocalBindings(binding)) {
-            return true;
-          }
-        }
-        return false;
-      }
-
-      /**
-       * Returns {@code true} if {@code binding} is unscoped (or has {@link Reusable @Reusable}
-       * scope) and depends on multibindings with contributions declared within this component's
-       * modules, or if any of its unscoped or {@link Reusable @Reusable} scoped dependencies depend
-       * on such local multibindings.
-       *
-       * <p>We don't care about non-reusable scoped dependencies because they will never depend on
-       * multibindings with contributions from subcomponents.
-       */
-      boolean dependsOnLocalBindings(Binding binding) {
-        if (!cycleChecker.add(binding)) {
-          return false;
-        }
-        return reentrantComputeIfAbsent(
-            bindingDependsOnLocalBindingsCache, binding, this::dependsOnLocalBindingsUncached);
-      }
-
-      private boolean dependsOnLocalBindingsUncached(Binding binding) {
-        if ((!binding.scope().isPresent() || binding.scope().get().isReusable())
-            // TODO(beder): Figure out what happens with production subcomponents.
-            && !binding.bindingType().equals(BindingType.PRODUCTION)) {
-          for (DependencyRequest dependency : binding.dependencies()) {
-            if (dependsOnLocalBindings(dependency.key())) {
-              return true;
-            }
-          }
-        }
-        return false;
-      }
-
-      /**
-       * Returns {@code true} if there is at least one multibinding contribution declared within
-       * this component's modules that matches the key.
-       */
-      private boolean hasLocalMultibindingContributions(Key requestKey) {
-        return keysMatchingRequest(requestKey)
-            .stream()
-            .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty());
-      }
-
-      /**
-       * Returns {@code true} if there is a contribution in this component for an {@code
-       * Optional<Foo>} key that has not been contributed in a parent.
-       */
-      private boolean hasLocalOptionalBindingContribution(ResolvedBindings resolvedBindings) {
-        if (resolvedBindings
-            .contributionBindings()
-            .stream()
-            .map(ContributionBinding::kind)
-            .anyMatch(isEqual(OPTIONAL))) {
-          return !getLocalExplicitBindings(keyFactory.unwrapOptional(resolvedBindings.key()).get())
-              .isEmpty();
-        } else {
-          // If a parent contributes a @Provides Optional<Foo> binding and a child has a
-          // @BindsOptionalOf Foo method, the two should conflict, even if there is no binding for
-          // Foo on its own
-          return !getOptionalBindingDeclarations(resolvedBindings.key()).isEmpty();
-        }
-      }
-    }
-  }
-
-  /**
-   * A multimap of those {@code declarations} that are multibinding contribution declarations,
-   * indexed by the key of the set or map to which they contribute.
-   */
-  static <T extends BindingDeclaration>
-      ImmutableSetMultimap<Key, T> multibindingContributionsByMultibindingKey(
-          Iterable<T> declarations) {
-    ImmutableSetMultimap.Builder<Key, T> builder = ImmutableSetMultimap.builder();
-    for (T declaration : declarations) {
-      if (declaration.key().multibindingContributionIdentifier().isPresent()) {
-        builder.put(
-            declaration
-                .key()
-                .toBuilder()
-                .multibindingContributionIdentifier(Optional.empty())
-                .build(),
-            declaration);
-      }
-    }
-    return builder.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraphPlugins.java b/java/dagger/internal/codegen/BindingGraphPlugins.java
deleted file mode 100644
index e2c3812..0000000
--- a/java/dagger/internal/codegen/BindingGraphPlugins.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.spi.BindingGraphPlugin;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-
-/** Initializes {@link BindingGraphPlugin}s. */
-final class BindingGraphPlugins {
-  private final ImmutableSet<BindingGraphPlugin> plugins;
-  private final Filer filer;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final Map<String, String> processingOptions;
-
-  @Inject
-  BindingGraphPlugins(
-      @Validation Set<BindingGraphPlugin> validationPlugins,
-      ImmutableSet<BindingGraphPlugin> externalPlugins,
-      Filer filer,
-      DaggerTypes types,
-      DaggerElements elements,
-      @ProcessingOptions Map<String, String> processingOptions) {
-    this.plugins = Sets.union(validationPlugins, externalPlugins).immutableCopy();
-    this.filer = filer;
-    this.types = types;
-    this.elements = elements;
-    this.processingOptions = processingOptions;
-  }
-
-  /** Returns {@link BindingGraphPlugin#supportedOptions()} from all the plugins. */
-  ImmutableSet<String> allSupportedOptions() {
-    return plugins.stream()
-        .flatMap(plugin -> plugin.supportedOptions().stream())
-        .collect(toImmutableSet());
-  }
-
-  /** Initializes the plugins. */
-  // TODO(ronshapiro): Should we validate the uniqueness of plugin names?
-  void initializePlugins() {
-    plugins.forEach(this::initializePlugin);
-  }
-
-  private void initializePlugin(BindingGraphPlugin plugin) {
-    plugin.initFiler(filer);
-    plugin.initTypes(types);
-    plugin.initElements(elements);
-    Set<String> supportedOptions = plugin.supportedOptions();
-    if (!supportedOptions.isEmpty()) {
-      plugin.initOptions(Maps.filterKeys(processingOptions, supportedOptions::contains));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraphStatisticsCollector.java b/java/dagger/internal/codegen/BindingGraphStatisticsCollector.java
deleted file mode 100644
index 129647f..0000000
--- a/java/dagger/internal/codegen/BindingGraphStatisticsCollector.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2019 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.errorprone.util.ASTHelpers.getSymbol;
-import static dagger.internal.codegen.ComponentAnnotation.rootComponentAnnotation;
-
-import com.google.errorprone.VisitorState;
-import com.google.errorprone.bugpatterns.BugChecker;
-import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
-import com.google.errorprone.matchers.Description;
-import com.sun.source.tree.ClassTree;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.util.Context;
-import dagger.BindsInstance;
-import dagger.Component;
-import dagger.model.BindingGraph;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/** A {@link BugChecker} that collects statistics derived from a {@link BindingGraph}. */
-public abstract class BindingGraphStatisticsCollector extends BugChecker
-    implements ClassTreeMatcher {
-  private BindingGraphConverter bindingGraphConverter;
-  private BindingGraphFactory bindingGraphFactory;
-  private ComponentDescriptorFactory componentDescriptorFactory;
-  private boolean isInjected;
-
-  @Singleton
-  @Component(modules = JavacPluginModule.class)
-  interface Injector {
-    void inject(BindingGraphStatisticsCollector collector);
-
-    @Component.Factory
-    interface Factory {
-      Injector create(@BindsInstance Context context);
-    }
-  }
-
-  // BugCheckers must have no-arg constructors, so we'll use method injection instead.
-  @Inject
-  void inject(
-      BindingGraphConverter bindingGraphConverter,
-      BindingGraphFactory bindingGraphFactory,
-      ComponentDescriptorFactory componentDescriptorFactory) {
-    this.bindingGraphConverter = bindingGraphConverter;
-    this.bindingGraphFactory = bindingGraphFactory;
-    this.componentDescriptorFactory = componentDescriptorFactory;
-  }
-
-  @Override
-  public final Description matchClass(ClassTree tree, VisitorState state) {
-    injectIfNecessary(state.context);
-
-    ClassSymbol symbol = getSymbol(tree);
-    rootComponentAnnotation(symbol)
-        .map(annotation -> createBindingGraph(symbol))
-        .ifPresent(graph -> visitBindingGraph(graph, state));
-
-    return Description.NO_MATCH;
-  }
-
-  private BindingGraph createBindingGraph(ClassSymbol component) {
-    return bindingGraphConverter.convert(
-        bindingGraphFactory.create(
-            componentDescriptorFactory.rootComponentDescriptor(component), false));
-  }
-
-  /** Visits a {@link BindingGraph} and emits stats to a {@link VisitorState}. */
-  protected abstract void visitBindingGraph(BindingGraph graph, VisitorState state);
-
-  private void injectIfNecessary(Context context) {
-    if (isInjected) {
-      return;
-    }
-    DaggerBindingGraphStatisticsCollector_Injector.factory().create(context).inject(this);
-    isInjected = true;
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingGraphValidationModule.java b/java/dagger/internal/codegen/BindingGraphValidationModule.java
deleted file mode 100644
index 63e1fa2..0000000
--- a/java/dagger/internal/codegen/BindingGraphValidationModule.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.IntoSet;
-import dagger.spi.BindingGraphPlugin;
-
-/** Binds the set of {@link BindingGraphPlugin}s used to implement Dagger validation. */
-@Module
-interface BindingGraphValidationModule {
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin dependencyCycle(DependencyCycleValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin dependsOnProductionExecutor(DependsOnProductionExecutorValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin duplicateBindings(DuplicateBindingsValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin incompatiblyScopedBindings(IncompatiblyScopedBindingsValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin injectBinding(InjectBindingValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin mapMultibinding(MapMultibindingValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin missingBinding(MissingBindingValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin nullableBinding(NullableBindingValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin provisionDependencyOnProducerBinding(
-      ProvisionDependencyOnProducerBindingValidator validation);
-
-  @Binds
-  @IntoSet
-  @Validation
-  BindingGraphPlugin subcomponentFactoryMethod(SubcomponentFactoryMethodValidator validation);
-}
diff --git a/java/dagger/internal/codegen/BindingGraphValidator.java b/java/dagger/internal/codegen/BindingGraphValidator.java
deleted file mode 100644
index df17b15..0000000
--- a/java/dagger/internal/codegen/BindingGraphValidator.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.internal.codegen.DiagnosticReporterFactory.DiagnosticReporterImpl;
-import dagger.model.BindingGraph;
-import dagger.spi.BindingGraphPlugin;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/** Validates a {@link BindingGraph}. */
-@Singleton
-final class BindingGraphValidator {
-  private final ImmutableSet<BindingGraphPlugin> validationPlugins;
-  private final ImmutableSet<BindingGraphPlugin> externalPlugins;
-  private final DiagnosticReporterFactory diagnosticReporterFactory;
-
-  @Inject
-  BindingGraphValidator(
-      @Validation Set<BindingGraphPlugin> validationPlugins,
-      ImmutableSet<BindingGraphPlugin> externalPlugins,
-      DiagnosticReporterFactory diagnosticReporterFactory) {
-    this.validationPlugins = ImmutableSet.copyOf(validationPlugins);
-    this.externalPlugins = ImmutableSet.copyOf(externalPlugins);
-    this.diagnosticReporterFactory = checkNotNull(diagnosticReporterFactory);
-  }
-
-  /** Returns {@code true} if no errors are reported for {@code graph}. */
-  boolean isValid(BindingGraph graph) {
-    return isValid(validationPlugins, graph) && isValid(externalPlugins, graph);
-  }
-
-  private boolean isValid(ImmutableSet<BindingGraphPlugin> plugins, BindingGraph graph) {
-    boolean isValid = true;
-    for (BindingGraphPlugin plugin : plugins) {
-      DiagnosticReporterImpl reporter = diagnosticReporterFactory.reporter(graph, plugin);
-      plugin.visitGraph(graph, reporter);
-      if (reporter.reportedDiagnosticKinds().contains(ERROR)) {
-        isValid = false;
-      }
-    }
-    return isValid;
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingMethodProcessingStep.java b/java/dagger/internal/codegen/BindingMethodProcessingStep.java
deleted file mode 100644
index e6c4f8e..0000000
--- a/java/dagger/internal/codegen/BindingMethodProcessingStep.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-
-/** A step that validates all binding methods that were not validated while processing modules. */
-final class BindingMethodProcessingStep extends TypeCheckingProcessingStep<ExecutableElement> {
-
-  private final Messager messager;
-  private final AnyBindingMethodValidator anyBindingMethodValidator;
-
-  @Inject
-  BindingMethodProcessingStep(
-      Messager messager, AnyBindingMethodValidator anyBindingMethodValidator) {
-    super(MoreElements::asExecutable);
-    this.messager = messager;
-    this.anyBindingMethodValidator = anyBindingMethodValidator;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return anyBindingMethodValidator.methodAnnotations();
-  }
-
-  @Override
-  protected void process(
-      ExecutableElement method, ImmutableSet<Class<? extends Annotation>> annotations) {
-    checkArgument(
-        anyBindingMethodValidator.isBindingMethod(method),
-        "%s is not annotated with any of %s",
-        method,
-        annotations());
-    if (!anyBindingMethodValidator.wasAlreadyValidated(method)) {
-      anyBindingMethodValidator.validate(method).printMessagesTo(messager);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingMethodValidator.java b/java/dagger/internal/codegen/BindingMethodValidator.java
deleted file mode 100644
index 21c05cc..0000000
--- a/java/dagger/internal/codegen/BindingMethodValidator.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-import static java.util.stream.Collectors.joining;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.errorprone.annotations.FormatMethod;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for methods that represent binding declarations. */
-abstract class BindingMethodValidator extends BindingElementValidator<ExecutableElement> {
-
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final DependencyRequestValidator dependencyRequestValidator;
-  private final Class<? extends Annotation> methodAnnotation;
-  private final ImmutableSet<? extends Class<? extends Annotation>> enclosingElementAnnotations;
-  private final Abstractness abstractness;
-  private final ExceptionSuperclass exceptionSuperclass;
-
-  /**
-   * Creates a validator object.
-   *
-   * @param methodAnnotation the annotation on a method that identifies it as a binding method
-   * @param enclosingElementAnnotation the method must be declared in a class or interface annotated
-   *     with this annotation
-   */
-  protected BindingMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator,
-      Class<? extends Annotation> methodAnnotation,
-      Class<? extends Annotation> enclosingElementAnnotation,
-      Abstractness abstractness,
-      ExceptionSuperclass exceptionSuperclass,
-      AllowsMultibindings allowsMultibindings,
-      AllowsScoping allowsScoping) {
-    this(
-        elements,
-        types,
-        methodAnnotation,
-        ImmutableSet.of(enclosingElementAnnotation),
-        dependencyRequestValidator,
-        abstractness,
-        exceptionSuperclass,
-        allowsMultibindings,
-        allowsScoping);
-  }
-
-  /**
-   * Creates a validator object.
-   *
-   * @param methodAnnotation the annotation on a method that identifies it as a binding method
-   * @param enclosingElementAnnotations the method must be declared in a class or interface
-   *     annotated with one of these annotations
-   */
-  protected BindingMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      Class<? extends Annotation> methodAnnotation,
-      Iterable<? extends Class<? extends Annotation>> enclosingElementAnnotations,
-      DependencyRequestValidator dependencyRequestValidator,
-      Abstractness abstractness,
-      ExceptionSuperclass exceptionSuperclass,
-      AllowsMultibindings allowsMultibindings,
-      AllowsScoping allowsScoping) {
-    super(methodAnnotation, allowsMultibindings, allowsScoping);
-    this.elements = elements;
-    this.types = types;
-    this.methodAnnotation = methodAnnotation;
-    this.enclosingElementAnnotations = ImmutableSet.copyOf(enclosingElementAnnotations);
-    this.dependencyRequestValidator = dependencyRequestValidator;
-    this.abstractness = abstractness;
-    this.exceptionSuperclass = exceptionSuperclass;
-  }
-
-  /** The annotation that identifies binding methods validated by this object. */
-  final Class<? extends Annotation> methodAnnotation() {
-    return methodAnnotation;
-  }
-
-  /**
-   * Returns an error message of the form "@<i>annotation</i> methods <i>rule</i>", where
-   * <i>rule</i> comes from calling {@link String#format(String, Object...)} on {@code ruleFormat}
-   * and the other arguments.
-   */
-  @FormatMethod
-  protected final String bindingMethods(String ruleFormat, Object... args) {
-    return bindingElements(ruleFormat, args);
-  }
-
-  @Override
-  protected final String bindingElements() {
-    return String.format("@%s methods", methodAnnotation.getSimpleName());
-  }
-
-  @Override
-  protected final String bindingElementTypeVerb() {
-    return "return";
-  }
-
-  /** Abstract validator for individual binding method elements. */
-  protected abstract class MethodValidator extends ElementValidator {
-    protected MethodValidator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected final Optional<TypeMirror> bindingElementType() {
-      return Optional.of(element.getReturnType());
-    }
-
-    @Override
-    protected final void checkAdditionalProperties() {
-      checkEnclosingElement();
-      checkTypeParameters();
-      checkNotPrivate();
-      checkAbstractness();
-      checkThrows();
-      checkParameters();
-      checkAdditionalMethodProperties();
-    }
-
-    /** Checks additional properties of the binding method. */
-    protected void checkAdditionalMethodProperties() {}
-
-    /**
-     * Adds an error if the method is not declared in a class or interface annotated with one of the
-     * {@link #enclosingElementAnnotations}.
-     */
-    private void checkEnclosingElement() {
-      if (!isAnyAnnotationPresent(
-          element.getEnclosingElement(), enclosingElementAnnotations)) {
-        report.addError(
-            bindingMethods(
-                "can only be present within a @%s",
-                enclosingElementAnnotations.stream()
-                    .map(Class::getSimpleName)
-                    .collect(joining(" or @"))));
-      }
-    }
-
-    /** Adds an error if the method is generic. */
-    private void checkTypeParameters() {
-      if (!element.getTypeParameters().isEmpty()) {
-        report.addError(bindingMethods("may not have type parameters"));
-      }
-    }
-
-    /** Adds an error if the method is private. */
-    private void checkNotPrivate() {
-      if (element.getModifiers().contains(PRIVATE)) {
-        report.addError(bindingMethods("cannot be private"));
-      }
-    }
-
-    /** Adds an error if the method is abstract but must not be, or is not and must be. */
-    private void checkAbstractness() {
-      boolean isAbstract = element.getModifiers().contains(ABSTRACT);
-      switch (abstractness) {
-        case MUST_BE_ABSTRACT:
-          if (!isAbstract) {
-            report.addError(bindingMethods("must be abstract"));
-          }
-          break;
-
-        case MUST_BE_CONCRETE:
-          if (isAbstract) {
-            report.addError(bindingMethods("cannot be abstract"));
-          }
-      }
-    }
-
-    /**
-     * Adds an error if the method declares throws anything but an {@link Error} or an appropriate
-     * subtype of {@link Exception}.
-     */
-    private void checkThrows() {
-      exceptionSuperclass.checkThrows(BindingMethodValidator.this, element, report);
-    }
-
-    /** Adds errors for the method parameters. */
-    protected void checkParameters() {
-      for (VariableElement parameter : element.getParameters()) {
-        checkParameter(parameter);
-      }
-    }
-
-    /**
-     * Adds errors for a method parameter. This implementation reports an error if the parameter has
-     * more than one qualifier.
-     */
-    protected void checkParameter(VariableElement parameter) {
-      dependencyRequestValidator.validateDependencyRequest(report, parameter, parameter.asType());
-    }
-  }
-
-  /** An abstract/concrete restriction on methods. */
-  protected enum Abstractness {
-    MUST_BE_ABSTRACT,
-    MUST_BE_CONCRETE
-  }
-
-  /**
-   * The exception class that all {@code throws}-declared throwables must extend, other than {@link
-   * Error}.
-   */
-  protected enum ExceptionSuperclass {
-    /** Methods may not declare any throwable types. */
-    NO_EXCEPTIONS {
-      @Override
-      protected String errorMessage(BindingMethodValidator validator) {
-        return validator.bindingMethods("may not throw");
-      }
-
-      @Override
-      protected void checkThrows(
-          BindingMethodValidator validator,
-          ExecutableElement element,
-          ValidationReport.Builder<ExecutableElement> report) {
-        if (!element.getThrownTypes().isEmpty()) {
-          report.addError(validator.bindingMethods("may not throw"));
-          return;
-        }
-      }
-    },
-
-    /** Methods may throw checked or unchecked exceptions or errors. */
-    EXCEPTION(Exception.class) {
-      @Override
-      protected String errorMessage(BindingMethodValidator validator) {
-        return validator.bindingMethods(
-            "may only throw unchecked exceptions or exceptions subclassing Exception");
-      }
-    },
-
-    /** Methods may throw unchecked exceptions or errors. */
-    RUNTIME_EXCEPTION(RuntimeException.class) {
-      @Override
-      protected String errorMessage(BindingMethodValidator validator) {
-        return validator.bindingMethods("may only throw unchecked exceptions");
-      }
-    },
-    ;
-
-    private final Class<? extends Exception> superclass;
-
-    ExceptionSuperclass() {
-      this(null);
-    }
-
-    ExceptionSuperclass(Class<? extends Exception> superclass) {
-      this.superclass = superclass;
-    }
-
-    /**
-     * Adds an error if the method declares throws anything but an {@link Error} or an appropriate
-     * subtype of {@link Exception}.
-     *
-     * <p>This method is overridden in {@link #NO_EXCEPTIONS}.
-     */
-    protected void checkThrows(
-        BindingMethodValidator validator,
-        ExecutableElement element,
-        ValidationReport.Builder<ExecutableElement> report) {
-      TypeMirror exceptionSupertype = validator.elements.getTypeElement(superclass).asType();
-      TypeMirror errorType = validator.elements.getTypeElement(Error.class).asType();
-      for (TypeMirror thrownType : element.getThrownTypes()) {
-        if (!validator.types.isSubtype(thrownType, exceptionSupertype)
-            && !validator.types.isSubtype(thrownType, errorType)) {
-          report.addError(errorMessage(validator));
-          break;
-        }
-      }
-    }
-
-    protected abstract String errorMessage(BindingMethodValidator validator);
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingMethodValidatorsModule.java b/java/dagger/internal/codegen/BindingMethodValidatorsModule.java
deleted file mode 100644
index 28a272d..0000000
--- a/java/dagger/internal/codegen/BindingMethodValidatorsModule.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Maps.uniqueIndex;
-
-import com.google.common.collect.ImmutableMap;
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-
-/**
- * Binds each {@link BindingMethodValidator} into a map, keyed by {@link
- * BindingMethodValidator#methodAnnotation()}.
- */
-@Module
-interface BindingMethodValidatorsModule {
-  @Provides
-  static ImmutableMap<Class<? extends Annotation>, BindingMethodValidator> indexValidators(
-      Set<BindingMethodValidator> validators) {
-    return uniqueIndex(validators, BindingMethodValidator::methodAnnotation);
-  }
-
-  @Binds
-  @IntoSet
-  BindingMethodValidator provides(ProvidesMethodValidator validator);
-
-  @Binds
-  @IntoSet
-  BindingMethodValidator produces(ProducesMethodValidator validator);
-
-  @Binds
-  @IntoSet
-  BindingMethodValidator binds(BindsMethodValidator validator);
-
-  @Binds
-  @IntoSet
-  BindingMethodValidator multibinds(MultibindsMethodValidator validator);
-
-  @Binds
-  @IntoSet
-  BindingMethodValidator bindsOptionalOf(BindsOptionalOfMethodValidator validator);
-}
diff --git a/java/dagger/internal/codegen/BindingNode.java b/java/dagger/internal/codegen/BindingNode.java
deleted file mode 100644
index a7da092..0000000
--- a/java/dagger/internal/codegen/BindingNode.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static dagger.internal.codegen.BindingType.PRODUCTION;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.model.BindingKind;
-import dagger.model.ComponentPath;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.Scope;
-import dagger.multibindings.Multibinds;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * An implementation of {@link dagger.model.Binding} that also exposes {@link BindingDeclaration}s
- * associated with the binding.
- */
-// TODO(dpb): Consider a supertype of dagger.model.Binding that dagger.internal.codegen.Binding
-// could also implement.
-@AutoValue
-abstract class BindingNode implements dagger.model.Binding {
-  static BindingNode create(
-      ComponentPath component,
-      Binding delegate,
-      ImmutableSet<MultibindingDeclaration> multibindingDeclarations,
-      ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations,
-      ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations,
-      BindingDeclarationFormatter bindingDeclarationFormatter) {
-    BindingNode node =
-        new AutoValue_BindingNode(
-            component,
-            delegate,
-            multibindingDeclarations,
-            optionalBindingDeclarations,
-            subcomponentDeclarations);
-    node.bindingDeclarationFormatter = checkNotNull(bindingDeclarationFormatter);
-    return node;
-  }
-
-  private BindingDeclarationFormatter bindingDeclarationFormatter;
-
-  abstract Binding delegate();
-
-  abstract ImmutableSet<MultibindingDeclaration> multibindingDeclarations();
-
-  abstract ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations();
-
-  abstract ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations();
-
-  /**
-   * The {@link Element}s (other than the binding's {@link #bindingElement()}) that are associated
-   * with the binding.
-   *
-   * <ul>
-   *   <li>{@linkplain BindsOptionalOf optional binding} declarations
-   *   <li>{@linkplain Module#subcomponents() module subcomponent} declarations
-   *   <li>{@linkplain Multibinds multibinding} declarations
-   * </ul>
-   */
-  final Iterable<BindingDeclaration> associatedDeclarations() {
-    return Iterables.concat(
-        multibindingDeclarations(), optionalBindingDeclarations(), subcomponentDeclarations());
-  }
-
-  @Override
-  public Key key() {
-    return delegate().key();
-  }
-
-  @Override
-  public ImmutableSet<DependencyRequest> dependencies() {
-    return delegate().dependencies();
-  }
-
-  @Override
-  public Optional<Element> bindingElement() {
-    return delegate().bindingElement();
-  }
-
-  @Override
-  public Optional<TypeElement> contributingModule() {
-    return delegate().contributingModule();
-  }
-
-  @Override
-  public boolean requiresModuleInstance() {
-    return delegate().requiresModuleInstance();
-  }
-
-  @Override
-  public Optional<Scope> scope() {
-    return delegate().scope();
-  }
-
-  @Override
-  public boolean isNullable() {
-    return delegate().isNullable();
-  }
-
-  @Override
-  public boolean isProduction() {
-    return delegate().bindingType().equals(PRODUCTION);
-  }
-
-  @Override
-  public BindingKind kind() {
-    return delegate().kind();
-  }
-
-  @Override
-  public final String toString() {
-    return bindingDeclarationFormatter.format(delegate());
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingRequest.java b/java/dagger/internal/codegen/BindingRequest.java
deleted file mode 100644
index 27067aa..0000000
--- a/java/dagger/internal/codegen/BindingRequest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.RequestKinds.requestType;
-
-import com.google.auto.value.AutoValue;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.internal.codegen.serialization.BindingRequestProto;
-import dagger.internal.codegen.serialization.FrameworkTypeWrapper;
-import dagger.internal.codegen.serialization.RequestKindWrapper;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A request for a binding, which may be in the form of a request for a dependency to pass to a
- * constructor or module method ({@link RequestKind}) or an internal request for a framework
- * instance ({@link FrameworkType}).
- */
-@AutoValue
-abstract class BindingRequest {
-  /** Creates a {@link BindingRequest} for the given {@link DependencyRequest}. */
-  static BindingRequest bindingRequest(DependencyRequest dependencyRequest) {
-    return bindingRequest(dependencyRequest.key(), dependencyRequest.kind());
-  }
-
-  /**
-   * Creates a {@link BindingRequest} for a normal dependency request for the given {@link Key} and
-   * {@link RequestKind}.
-   */
-  static BindingRequest bindingRequest(Key key, RequestKind requestKind) {
-    // When there's a request that has a 1:1 mapping to a FrameworkType, the request should be
-    // associated with that FrameworkType as well, because we want to ensure that if a request
-    // comes in for that as a dependency first and as a framework instance later, they resolve to
-    // the same binding expression.
-    // TODO(cgdecker): Instead of doing this, make ComponentBindingExpressions create a
-    // BindingExpression for the RequestKind that simply delegates to the BindingExpression for the
-    // FrameworkType. Then there are separate BindingExpressions, but we don't end up doing weird
-    // things like creating two fields when there should only be one.
-    return new AutoValue_BindingRequest(
-        key, Optional.of(requestKind), FrameworkType.forRequestKind(requestKind));
-  }
-
-  /**
-   * Creates a {@link BindingRequest} for a request for a framework instance for the given {@link
-   * Key} with the given {@link FrameworkType}.
-   */
-  static BindingRequest bindingRequest(Key key, FrameworkType frameworkType) {
-    return new AutoValue_BindingRequest(
-        key, frameworkType.requestKind(), Optional.of(frameworkType));
-  }
-
-  /** Creates a {@link BindingRequest} for the given {@link FrameworkDependency}. */
-  static BindingRequest bindingRequest(FrameworkDependency frameworkDependency) {
-    return bindingRequest(frameworkDependency.key(), frameworkDependency.frameworkType());
-  }
-
-  /** Returns the {@link Key} for the requested binding. */
-  abstract Key key();
-
-  /** Returns the request kind associated with this request, if any. */
-  abstract Optional<RequestKind> requestKind();
-
-  /** Returns the framework type associated with this request, if any. */
-  abstract Optional<FrameworkType> frameworkType();
-
-  /** Returns whether this request is of the given kind. */
-  final boolean isRequestKind(RequestKind requestKind) {
-    return requestKind.equals(requestKind().orElse(null));
-  }
-
-  final TypeMirror requestedType(TypeMirror contributedType, DaggerTypes types) {
-    if (requestKind().isPresent()) {
-      return requestType(requestKind().get(), contributedType, types);
-    }
-    return types.wrapType(contributedType, frameworkType().get().frameworkClass());
-  }
-
-  /** Returns a name that can be used for the kind of request this is. */
-  final String kindName() {
-    Object requestKindObject =
-        requestKind().isPresent()
-            ? requestKind().get()
-            : frameworkType().get().frameworkClass().getSimpleName();
-    return requestKindObject.toString();
-  }
-
-  /** Returns {@code true} if this request can be satisfied by a production binding. */
-  final boolean canBeSatisfiedByProductionBinding() {
-    if (requestKind().isPresent()) {
-      return RequestKinds.canBeSatisfiedByProductionBinding(requestKind().get());
-    }
-    return frameworkType().get().equals(FrameworkType.PRODUCER_NODE);
-  }
-
-  /** Creates a proto representation of this binding request. */
-  BindingRequestProto toProto() {
-    BindingRequestProto.Builder builder =
-        BindingRequestProto.newBuilder().setKey(KeyFactory.toProto(key()));
-    if (frameworkType().isPresent()) {
-      builder.setFrameworkType(
-          FrameworkTypeWrapper.FrameworkType.valueOf(frameworkType().get().name()));
-    } else {
-      builder.setRequestKind(RequestKindWrapper.RequestKind.valueOf(requestKind().get().name()));
-    }
-    return builder.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/BindingType.java b/java/dagger/internal/codegen/BindingType.java
deleted file mode 100644
index 37109c7..0000000
--- a/java/dagger/internal/codegen/BindingType.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.MembersInjector;
-
-/** Whether a binding or declaration is for provision, production, or a {@link MembersInjector}. */
-enum BindingType {
-  /** A binding with this type is a {@link ProvisionBinding}. */
-  PROVISION,
-
-  /** A binding with this type is a {@link MembersInjectionBinding}. */
-  MEMBERS_INJECTION,
-
-  /** A binding with this type is a {@link ProductionBinding}. */
-  PRODUCTION,
-}
diff --git a/java/dagger/internal/codegen/BindsInstanceElementValidator.java b/java/dagger/internal/codegen/BindsInstanceElementValidator.java
deleted file mode 100644
index 9249c8e..0000000
--- a/java/dagger/internal/codegen/BindsInstanceElementValidator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.BindsInstance;
-import javax.lang.model.element.Element;
-
-abstract class BindsInstanceElementValidator<E extends Element> extends BindingElementValidator<E> {
-  BindsInstanceElementValidator() {
-    super(BindsInstance.class, AllowsMultibindings.NO_MULTIBINDINGS, AllowsScoping.NO_SCOPING);
-  }
-
-  @Override
-  protected final String bindingElements() {
-    // Even though @BindsInstance may be placed on methods, the subject of errors is the
-    // parameter
-    return "@BindsInstance parameters";
-  }
-
-  @Override
-  protected final String bindingElementTypeVerb() {
-    return "be";
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsInstanceMethodValidator.java b/java/dagger/internal/codegen/BindsInstanceMethodValidator.java
deleted file mode 100644
index 1a491c7..0000000
--- a/java/dagger/internal/codegen/BindsInstanceMethodValidator.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentAnnotation.anyComponentAnnotation;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-
-import com.google.auto.common.MoreElements;
-import java.util.List;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-final class BindsInstanceMethodValidator extends BindsInstanceElementValidator<ExecutableElement> {
-  @Inject
-  BindsInstanceMethodValidator() {}
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends ElementValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkAdditionalProperties() {
-      if (!element.getModifiers().contains(ABSTRACT)) {
-        report.addError("@BindsInstance methods must be abstract");
-      }
-      if (element.getParameters().size() != 1) {
-        report.addError(
-            "@BindsInstance methods should have exactly one parameter for the bound type");
-      }
-      TypeElement enclosingType = MoreElements.asType(element.getEnclosingElement());
-      moduleAnnotation(enclosingType)
-          .ifPresent(moduleAnnotation -> report.addError(didYouMeanBinds(moduleAnnotation)));
-      anyComponentAnnotation(enclosingType)
-          .ifPresent(
-              componentAnnotation ->
-                  report.addError(
-                      String.format(
-                          "@BindsInstance methods should not be included in @%1$ss. "
-                              + "Did you mean to put it in a @%1$s.Builder?",
-                          componentAnnotation.simpleName())));
-    }
-
-    @Override
-    protected Optional<TypeMirror> bindingElementType() {
-      List<? extends VariableElement> parameters =
-          MoreElements.asExecutable(element).getParameters();
-      return parameters.size() == 1
-          ? Optional.of(getOnlyElement(parameters).asType())
-          : Optional.empty();
-    }
-  }
-
-  private static String didYouMeanBinds(ModuleAnnotation moduleAnnotation) {
-    return String.format(
-        "@BindsInstance methods should not be included in @%ss. Did you mean @Binds?",
-        moduleAnnotation.annotationClass().getSimpleName());
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsInstanceParameterValidator.java b/java/dagger/internal/codegen/BindsInstanceParameterValidator.java
deleted file mode 100644
index b2dc8d8..0000000
--- a/java/dagger/internal/codegen/BindsInstanceParameterValidator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 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 javax.lang.model.element.ElementKind.METHOD;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.type.TypeKind.DECLARED;
-import static javax.lang.model.type.TypeKind.TYPEVAR;
-
-import com.google.auto.common.MoreElements;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-final class BindsInstanceParameterValidator extends BindsInstanceElementValidator<VariableElement> {
-  @Inject
-  BindsInstanceParameterValidator() {}
-
-  @Override
-  protected ElementValidator elementValidator(VariableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends ElementValidator {
-    Validator(VariableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkAdditionalProperties() {
-      Element enclosing = element.getEnclosingElement();
-      if (!enclosing.getKind().equals(METHOD)) {
-        report.addError(
-            "@BindsInstance should only be applied to methods or parameters of methods");
-        return;
-      }
-
-      ExecutableElement method = MoreElements.asExecutable(enclosing);
-      if (!method.getModifiers().contains(ABSTRACT)) {
-        report.addError("@BindsInstance parameters may only be used in abstract methods");
-      }
-
-      TypeKind returnKind = method.getReturnType().getKind();
-      if (!(returnKind.equals(DECLARED) || returnKind.equals(TYPEVAR))) {
-        report.addError(
-            "@BindsInstance parameters may not be used in methods with a void, array or primitive "
-                + "return type");
-      }
-    }
-
-    @Override
-    protected Optional<TypeMirror> bindingElementType() {
-      return Optional.of(element.asType());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsInstanceProcessingStep.java b/java/dagger/internal/codegen/BindsInstanceProcessingStep.java
deleted file mode 100644
index 4c222a9..0000000
--- a/java/dagger/internal/codegen/BindsInstanceProcessingStep.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import dagger.BindsInstance;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-
-/**
- * Processing step that validates that the {@code BindsInstance} annotation is applied to the
- * correct elements.
- */
-final class BindsInstanceProcessingStep extends TypeCheckingProcessingStep<Element> {
-  private final BindsInstanceMethodValidator methodValidator;
-  private final BindsInstanceParameterValidator parameterValidator;
-  private final Messager messager;
-
-  @Inject
-  BindsInstanceProcessingStep(
-      BindsInstanceMethodValidator methodValidator,
-      BindsInstanceParameterValidator parameterValidator,
-      Messager messager) {
-    super(element -> element);
-    this.methodValidator = methodValidator;
-    this.parameterValidator = parameterValidator;
-    this.messager = messager;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(BindsInstance.class);
-  }
-
-  @Override
-  protected void process(Element element, ImmutableSet<Class<? extends Annotation>> annotations) {
-    switch (element.getKind()) {
-      case PARAMETER:
-        parameterValidator.validate(MoreElements.asVariable(element)).printMessagesTo(messager);
-        break;
-      case METHOD:
-        methodValidator.validate(MoreElements.asExecutable(element)).printMessagesTo(messager);
-        break;
-      default:
-        throw new AssertionError(element);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsMethodValidator.java b/java/dagger/internal/codegen/BindsMethodValidator.java
deleted file mode 100644
index e198c3a..0000000
--- a/java/dagger/internal/codegen/BindsMethodValidator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.BindingElementValidator.AllowsMultibindings.ALLOWS_MULTIBINDINGS;
-import static dagger.internal.codegen.BindingElementValidator.AllowsScoping.ALLOWS_SCOPING;
-import static dagger.internal.codegen.BindingMethodValidator.Abstractness.MUST_BE_ABSTRACT;
-import static dagger.internal.codegen.BindingMethodValidator.ExceptionSuperclass.RUNTIME_EXCEPTION;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.Binds;
-import dagger.Module;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.producers.ProducerModule;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for {@link Binds} methods. */
-final class BindsMethodValidator extends BindingMethodValidator {
-  private final DaggerTypes types;
-  private final BindsTypeChecker bindsTypeChecker;
-
-  @Inject
-  BindsMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator) {
-    super(
-        elements,
-        types,
-        Binds.class,
-        ImmutableSet.of(Module.class, ProducerModule.class),
-        dependencyRequestValidator,
-        MUST_BE_ABSTRACT,
-        RUNTIME_EXCEPTION,
-        ALLOWS_MULTIBINDINGS,
-        ALLOWS_SCOPING);
-    this.types = types;
-    this.bindsTypeChecker = new BindsTypeChecker(types, elements);
-  }
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends MethodValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkParameters() {
-      if (element.getParameters().size() != 1) {
-        report.addError(
-            bindingMethods(
-                "must have exactly one parameter, whose type is assignable to the return type"));
-      } else {
-        super.checkParameters();
-      }
-    }
-
-    @Override
-    protected void checkParameter(VariableElement parameter) {
-      super.checkParameter(parameter);
-      TypeMirror leftHandSide = boxIfNecessary(element.getReturnType());
-      TypeMirror rightHandSide = parameter.asType();
-      ContributionType contributionType = ContributionType.fromBindingElement(element);
-      if (contributionType.equals(ContributionType.SET_VALUES) && !SetType.isSet(leftHandSide)) {
-        report.addError(
-            "@Binds @ElementsIntoSet methods must return a Set and take a Set parameter");
-      }
-
-      if (!bindsTypeChecker.isAssignable(rightHandSide, leftHandSide, contributionType)) {
-        // TODO(ronshapiro): clarify this error message for @ElementsIntoSet cases, where the
-        // right-hand-side might not be assignable to the left-hand-side, but still compatible with
-        // Set.addAll(Collection<? extends E>)
-        report.addError("@Binds methods' parameter type must be assignable to the return type");
-      }
-    }
-
-    private TypeMirror boxIfNecessary(TypeMirror maybePrimitive) {
-      if (maybePrimitive.getKind().isPrimitive()) {
-        return types.boxedClass(MoreTypes.asPrimitiveType(maybePrimitive)).asType();
-      }
-      return maybePrimitive;
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsOptionalOfMethodValidator.java b/java/dagger/internal/codegen/BindsOptionalOfMethodValidator.java
deleted file mode 100644
index e1c9d73..0000000
--- a/java/dagger/internal/codegen/BindsOptionalOfMethodValidator.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.BindingElementValidator.AllowsMultibindings.NO_MULTIBINDINGS;
-import static dagger.internal.codegen.BindingElementValidator.AllowsScoping.NO_SCOPING;
-import static dagger.internal.codegen.BindingMethodValidator.Abstractness.MUST_BE_ABSTRACT;
-import static dagger.internal.codegen.BindingMethodValidator.ExceptionSuperclass.NO_EXCEPTIONS;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
-import static dagger.internal.codegen.InjectionAnnotations.injectedConstructors;
-import static dagger.internal.codegen.Keys.isValidImplicitProvisionKey;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.producers.ProducerModule;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for {@link BindsOptionalOf} methods. */
-final class BindsOptionalOfMethodValidator extends BindingMethodValidator {
-
-  private final DaggerTypes types;
-
-  @Inject
-  BindsOptionalOfMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator) {
-    super(
-        elements,
-        types,
-        BindsOptionalOf.class,
-        ImmutableSet.of(Module.class, ProducerModule.class),
-        dependencyRequestValidator,
-        MUST_BE_ABSTRACT,
-        NO_EXCEPTIONS,
-        NO_MULTIBINDINGS,
-        NO_SCOPING);
-    this.types = types;
-  }
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends MethodValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkKeyType(TypeMirror keyType) {
-      super.checkKeyType(keyType);
-      if (isValidImplicitProvisionKey(
-              getQualifiers(element).stream().findFirst(), keyType, types)
-          && !injectedConstructors(MoreElements.asType(MoreTypes.asDeclared(keyType).asElement()))
-              .isEmpty()) {
-        report.addError(
-            "@BindsOptionalOf methods cannot return unqualified types that have an @Inject-"
-                + "annotated constructor because those are always present");
-      }
-    }
-
-    @Override
-    protected void checkParameters() {
-      if (!element.getParameters().isEmpty()) {
-        report.addError("@BindsOptionalOf methods cannot have parameters");
-      }
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/BindsTypeChecker.java b/java/dagger/internal/codegen/BindsTypeChecker.java
deleted file mode 100644
index acecc9e..0000000
--- a/java/dagger/internal/codegen/BindsTypeChecker.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Map;
-import java.util.Set;
-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;
-
-/**
- * Checks the assignability of one type to another, given a {@link ContributionType} context. This
- * is used by {@link BindsMethodValidator} to validate that the right-hand-side of a {@link
- * dagger.Binds} method is valid, as well as in {@link DelegateBindingExpression} when the
- * right-hand-side in generated code might be an erased type due to accessibility.
- */
-final class BindsTypeChecker {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  @Inject
-  BindsTypeChecker(DaggerTypes types, DaggerElements elements) {
-    this.types = types;
-    this.elements = elements;
-  }
-
-  /**
-   * Checks the assignability of {@code rightHandSide} to {@code leftHandSide} given a {@link
-   * ContributionType} context.
-   */
-  boolean isAssignable(
-      TypeMirror rightHandSide, TypeMirror leftHandSide, ContributionType contributionType) {
-    return types.isAssignable(rightHandSide, desiredAssignableType(leftHandSide, contributionType));
-  }
-
-  private TypeMirror desiredAssignableType(
-      TypeMirror leftHandSide, ContributionType contributionType) {
-    switch (contributionType) {
-      case UNIQUE:
-        return leftHandSide;
-      case SET:
-        DeclaredType parameterizedSetType = types.getDeclaredType(setElement(), leftHandSide);
-        return methodParameterType(parameterizedSetType, "add");
-      case SET_VALUES:
-        return methodParameterType(MoreTypes.asDeclared(leftHandSide), "addAll");
-      case MAP:
-        DeclaredType parameterizedMapType =
-            types.getDeclaredType(mapElement(), unboundedWildcard(), leftHandSide);
-        return methodParameterTypes(parameterizedMapType, "put").get(1);
-    }
-    throw new AssertionError("Unknown contribution type: " + contributionType);
-  }
-
-  private ImmutableList<TypeMirror> methodParameterTypes(DeclaredType type, String methodName) {
-    ImmutableList.Builder<ExecutableElement> methodsForName = ImmutableList.builder();
-    for (ExecutableElement method :
-        // type.asElement().getEnclosedElements() is not used because some non-standard JDKs (e.g.
-        // J2CL) don't redefine Set.add() (whose only purpose of being redefined in the standard JDK
-        // is documentation, and J2CL's implementation doesn't declare docs for JDK types).
-        // MoreElements.getLocalAndInheritedMethods ensures that the method will always be present.
-        MoreElements.getLocalAndInheritedMethods(MoreTypes.asTypeElement(type), types, elements)) {
-      if (method.getSimpleName().contentEquals(methodName)) {
-        methodsForName.add(method);
-      }
-    }
-    ExecutableElement method = getOnlyElement(methodsForName.build());
-    return ImmutableList.copyOf(
-        MoreTypes.asExecutable(types.asMemberOf(type, method)).getParameterTypes());
-  }
-
-  private TypeMirror methodParameterType(DeclaredType type, String methodName) {
-    return getOnlyElement(methodParameterTypes(type, methodName));
-  }
-
-  private TypeElement setElement() {
-    return elements.getTypeElement(Set.class);
-  }
-
-  private TypeElement mapElement() {
-    return elements.getTypeElement(Map.class);
-  }
-
-  private TypeMirror unboundedWildcard() {
-    return types.getWildcardType(null, null);
-  }
-}
diff --git a/java/dagger/internal/codegen/ChildFactoryMethodEdgeImpl.java b/java/dagger/internal/codegen/ChildFactoryMethodEdgeImpl.java
deleted file mode 100644
index a5e0219..0000000
--- a/java/dagger/internal/codegen/ChildFactoryMethodEdgeImpl.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.ElementFormatter.elementToString;
-
-import dagger.model.BindingGraph.ChildFactoryMethodEdge;
-import javax.lang.model.element.ExecutableElement;
-
-/** An implementation of {@link ChildFactoryMethodEdge}. */
-final class ChildFactoryMethodEdgeImpl implements ChildFactoryMethodEdge {
-
-  private final ExecutableElement factoryMethod;
-
-  ChildFactoryMethodEdgeImpl(ExecutableElement factoryMethod) {
-    this.factoryMethod = factoryMethod;
-  }
-
-  @Override
-  public ExecutableElement factoryMethod() {
-    return factoryMethod;
-  }
-
-  @Override
-  public String toString() {
-    return elementToString(factoryMethod);
-  }
-}
diff --git a/java/dagger/internal/codegen/ClearableCache.java b/java/dagger/internal/codegen/ClearableCache.java
deleted file mode 100644
index 66ce3ef..0000000
--- a/java/dagger/internal/codegen/ClearableCache.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-/** A cache of objects that can be cleared. */
-interface ClearableCache {
-  /** Releases cached references. */
-  void clearCache();
-}
diff --git a/java/dagger/internal/codegen/CompilerOptions.java b/java/dagger/internal/codegen/CompilerOptions.java
deleted file mode 100644
index bc3cbf8..0000000
--- a/java/dagger/internal/codegen/CompilerOptions.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.squareup.javapoet.AnnotationSpec;
-import dagger.internal.GenerationOptions;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-
-/** A collection of options that dictate how the compiler will run. */
-abstract class CompilerOptions {
-  abstract boolean usesProducers();
-
-  /**
-   * Returns true if the fast initialization flag, {@code fastInit}, is enabled.
-   *
-   * <p>If enabled, the generated code will attempt to optimize for fast component initialization.
-   * This is done by reducing the number of factory classes loaded during initialization and the
-   * number of eagerly initialized fields at the cost of potential memory leaks and higher
-   * per-provision instantiation time.
-   */
-  abstract boolean fastInit();
-
-  abstract boolean formatGeneratedSource();
-
-  abstract boolean writeProducerNameInToken();
-
-  abstract Diagnostic.Kind nullableValidationKind();
-
-  final boolean doCheckForNulls() {
-    return nullableValidationKind().equals(Diagnostic.Kind.ERROR);
-  }
-
-  abstract Diagnostic.Kind privateMemberValidationKind();
-
-  abstract Diagnostic.Kind staticMemberValidationKind();
-
-  /**
-   * If {@code true}, Dagger will generate factories and components even if some members-injected
-   * types have {@code private} or {@code static} {@code @Inject}-annotated members.
-   *
-   * <p>This should only ever be enabled by the TCK tests. Disabling this validation could lead to
-   * generating code that does not compile.
-   */
-  abstract boolean ignorePrivateAndStaticInjectionForComponent();
-
-  abstract ValidationType scopeCycleValidationType();
-
-  abstract boolean warnIfInjectionFactoryNotGeneratedUpstream();
-
-  abstract boolean headerCompilation();
-
-  abstract boolean aheadOfTimeSubcomponents();
-
-  /**
-   * Enables a testing configuration where all superclass {@link ComponentImplementation}s are
-   * derived from their serialized forms.
-   */
-  abstract boolean forceUseSerializedComponentImplementations();
-
-  /**
-   * If {@code true}, in {@link #aheadOfTimeSubcomponents()} mode, Dagger will emit metadata
-   * annotations to deserialize aspects of the {@link ComponentImplementation}.
-   *
-   * This should only be disabled in compile-testing tests that want to ignore the annotations when
-   * asserting on generated source.
-   */
-  abstract boolean emitModifiableMetadataAnnotations();
-
-  abstract boolean useGradleIncrementalProcessing();
-
-  /**
-   * Returns the validation that should be done for the full binding graph for the element.
-   *
-   * @throws IllegalArgumentException if {@code element} is not a module or (sub)component
-   */
-  abstract ValidationType fullBindingGraphValidationType(TypeElement element);
-
-  abstract Diagnostic.Kind moduleHasDifferentScopesDiagnosticKind();
-
-  abstract ValidationType explicitBindingConflictsWithInjectValidationType();
-
-  /**
-   * Creates a new {@link CompilerOptions} from the serialized {@link GenerationOptions} of a base
-   * component implementation.
-   */
-  final CompilerOptions withGenerationOptions(GenerationOptions generationOptions) {
-    return new ForwardingCompilerOptions(this) {
-      @Override
-      public boolean fastInit() {
-        return generationOptions.fastInit();
-      }
-    };
-  }
-
-  /**
-   * Returns a {@link GenerationOptions} annotation that serializes any options for this compilation
-   * that should be reused in future compilations.
-   */
-  final AnnotationSpec toGenerationOptionsAnnotation() {
-    return AnnotationSpec.builder(GenerationOptions.class)
-        .addMember("fastInit", "$L", fastInit())
-        .build();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentAnnotation.java b/java/dagger/internal/codegen/ComponentAnnotation.java
deleted file mode 100644
index a8f2ece..0000000
--- a/java/dagger/internal/codegen/ComponentAnnotation.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2019 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.auto.common.AnnotationMirrors.getAnnotationValue;
-import static com.google.auto.common.MoreTypes.asTypeElements;
-import static com.google.auto.common.MoreTypes.isTypeOf;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.MoreAnnotationValues.asAnnotationValues;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnyAnnotation;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import dagger.Component;
-import dagger.Subcomponent;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A {@code @Component}, {@code @Subcomponent}, {@code @ProductionComponent}, or
- * {@code @ProductionSubcomponent} annotation, or a {@code @Module} or {@code @ProducerModule}
- * annotation that is being treated as a component annotation when validating full binding graphs
- * for modules.
- */
-abstract class ComponentAnnotation {
-  /** The root component annotation types. */
-  private static final ImmutableSet<Class<? extends Annotation>> ROOT_COMPONENT_ANNOTATIONS =
-     ImmutableSet.of(Component.class, ProductionComponent.class);
-
-  /** The subcomponent annotation types. */
-  private static final ImmutableSet<Class<? extends Annotation>> SUBCOMPONENT_ANNOTATIONS =
-     ImmutableSet.of(Subcomponent.class, ProductionSubcomponent.class);
-
-  /** All component annotation types. */
-  private static final ImmutableSet<Class<? extends Annotation>> ALL_COMPONENT_ANNOTATIONS =
-     ImmutableSet.<Class<? extends Annotation>>builder()
-         .addAll(ROOT_COMPONENT_ANNOTATIONS)
-         .addAll(SUBCOMPONENT_ANNOTATIONS)
-         .build();
-
-  /** The annotation itself. */
-  abstract AnnotationMirror annotation();
-
-  /** The simple name of the annotation type. */
-  String simpleName() {
-    return MoreAnnotationMirrors.simpleName(annotation()).toString();
-  }
-
-  /**
-   * Returns {@code true} if the annotation is a {@code @Subcomponent} or
-   * {@code @ProductionSubcomponent}.
-   */
-  abstract boolean isSubcomponent();
-
-  /**
-   * Returns {@code true} if the annotation is a {@code @ProductionComponent},
-   * {@code @ProductionSubcomponent}, or {@code @ProducerModule}.
-   */
-  abstract boolean isProduction();
-
-  /**
-   * Returns {@code true} if the annotation is a real component annotation and not a module
-   * annotation.
-   */
-  abstract boolean isRealComponent();
-
-  /** The values listed as {@code dependencies}. */
-  abstract ImmutableList<AnnotationValue> dependencyValues();
-
-  /** The types listed as {@code dependencies}. */
-  ImmutableList<TypeMirror> dependencyTypes() {
-    return dependencyValues().stream().map(MoreAnnotationValues::asType).collect(toImmutableList());
-  }
-
-  /**
-   * The types listed as {@code dependencies}.
-   *
-   * @throws IllegalArgumentException if any of {@link #dependencyTypes()} are error types
-   */
-  ImmutableList<TypeElement> dependencies() {
-    return asTypeElements(dependencyTypes()).asList();
-  }
-
-  /** The values listed as {@code modules}. */
-  abstract ImmutableList<AnnotationValue> moduleValues();
-
-  /** The types listed as {@code modules}. */
-  ImmutableList<TypeMirror> moduleTypes() {
-    return moduleValues().stream().map(MoreAnnotationValues::asType).collect(toImmutableList());
-  }
-
-  /**
-   * The types listed as {@code modules}.
-   *
-   * @throws IllegalArgumentException if any of {@link #moduleTypes()} are error types
-   */
-  ImmutableSet<TypeElement> modules() {
-    return asTypeElements(moduleTypes());
-  }
-
-  protected final ImmutableList<AnnotationValue> getAnnotationValues(String parameterName) {
-    return asAnnotationValues(getAnnotationValue(annotation(), parameterName));
-  }
-
-  /**
-   * Returns an object representing a root component annotation, not a subcomponent annotation, if
-   * one is present on {@code typeElement}.
-   */
-  static Optional<ComponentAnnotation> rootComponentAnnotation(TypeElement typeElement) {
-    return anyComponentAnnotation(typeElement, ROOT_COMPONENT_ANNOTATIONS);
-  }
-
-  /**
-   * Returns an object representing a subcomponent annotation, if one is present on {@code
-   * typeElement}.
-   */
-  static Optional<ComponentAnnotation> subcomponentAnnotation(TypeElement typeElement) {
-    return anyComponentAnnotation(typeElement, SUBCOMPONENT_ANNOTATIONS);
-  }
-
-  /**
-   * Returns an object representing a root component or subcomponent annotation, if one is present
-   * on {@code typeElement}.
-   */
-  static Optional<ComponentAnnotation> anyComponentAnnotation(TypeElement typeElement) {
-    return anyComponentAnnotation(typeElement, ALL_COMPONENT_ANNOTATIONS);
-  }
-
-  private static Optional<ComponentAnnotation> anyComponentAnnotation(
-      TypeElement typeElement, Collection<Class<? extends Annotation>> annotations) {
-    return getAnyAnnotation(typeElement, annotations).map(ComponentAnnotation::componentAnnotation);
-  }
-
-  /** Returns {@code true} if the argument is a component annotation. */
-  static boolean isComponentAnnotation(AnnotationMirror annotation) {
-    return ALL_COMPONENT_ANNOTATIONS.stream()
-        .anyMatch(annotationClass -> isTypeOf(annotationClass, annotation.getAnnotationType()));
-  }
-
-  /** Creates an object representing a component or subcomponent annotation. */
-  static ComponentAnnotation componentAnnotation(AnnotationMirror annotation) {
-    RealComponentAnnotation.Builder annotationBuilder =
-        RealComponentAnnotation.builder().annotation(annotation);
-
-    if (isTypeOf(Component.class, annotation.getAnnotationType())) {
-      return annotationBuilder.isProduction(false).isSubcomponent(false).build();
-    }
-    if (isTypeOf(Subcomponent.class, annotation.getAnnotationType())) {
-      return annotationBuilder.isProduction(false).isSubcomponent(true).build();
-    }
-    if (isTypeOf(ProductionComponent.class, annotation.getAnnotationType())) {
-      return annotationBuilder.isProduction(true).isSubcomponent(false).build();
-    }
-    if (isTypeOf(ProductionSubcomponent.class, annotation.getAnnotationType())) {
-      return annotationBuilder.isProduction(true).isSubcomponent(true).build();
-    }
-    throw new IllegalArgumentException(
-        annotation
-            + " must be a Component, Subcomponent, ProductionComponent, "
-            + "or ProductionSubcomponent annotation");
-  }
-
-  /** Creates a fictional component annotation representing a module. */
-  static ComponentAnnotation fromModuleAnnotation(ModuleAnnotation moduleAnnotation) {
-    return new AutoValue_ComponentAnnotation_FictionalComponentAnnotation(moduleAnnotation);
-  }
-
-  /** The root component annotation types. */
-  static ImmutableSet<Class<? extends Annotation>> rootComponentAnnotations() {
-    return ROOT_COMPONENT_ANNOTATIONS;
-  }
-
-  /** The subcomponent annotation types. */
-  static ImmutableSet<Class<? extends Annotation>> subcomponentAnnotations() {
-    return SUBCOMPONENT_ANNOTATIONS;
-  }
-
-  /** All component annotation types. */
-  static ImmutableSet<Class<? extends Annotation>> allComponentAnnotations() {
-    return ALL_COMPONENT_ANNOTATIONS;
-  }
-
-  /**
-   * An actual component annotation.
-   *
-   * @see FictionalComponentAnnotation
-   */
-  @AutoValue
-  abstract static class RealComponentAnnotation extends ComponentAnnotation {
-
-    @Override
-    @Memoized
-    ImmutableList<AnnotationValue> dependencyValues() {
-      return isSubcomponent() ? ImmutableList.of() : getAnnotationValues("dependencies");
-    }
-
-    @Override
-    @Memoized
-    ImmutableList<TypeMirror> dependencyTypes() {
-      return super.dependencyTypes();
-    }
-
-    @Override
-    @Memoized
-    ImmutableList<TypeElement> dependencies() {
-      return super.dependencies();
-    }
-
-    @Override
-    boolean isRealComponent() {
-      return true;
-    }
-
-    @Override
-    @Memoized
-    ImmutableList<AnnotationValue> moduleValues() {
-      return getAnnotationValues("modules");
-    }
-
-    @Override
-    @Memoized
-    ImmutableList<TypeMirror> moduleTypes() {
-      return super.moduleTypes();
-    }
-
-    @Override
-    @Memoized
-    ImmutableSet<TypeElement> modules() {
-      return super.modules();
-    }
-
-    static Builder builder() {
-      return new AutoValue_ComponentAnnotation_RealComponentAnnotation.Builder();
-    }
-
-    @AutoValue.Builder
-    interface Builder {
-      Builder annotation(AnnotationMirror annotation);
-
-      Builder isSubcomponent(boolean isSubcomponent);
-
-      Builder isProduction(boolean isProduction);
-
-      RealComponentAnnotation build();
-    }
-  }
-
-  /**
-   * A fictional component annotation used to represent modules or other collections of bindings as
-   * a component.
-   */
-  @AutoValue
-  abstract static class FictionalComponentAnnotation extends ComponentAnnotation {
-
-    @Override
-    AnnotationMirror annotation() {
-      return moduleAnnotation().annotation();
-    }
-
-    @Override
-    boolean isSubcomponent() {
-      return false;
-    }
-
-    @Override
-    boolean isProduction() {
-      return moduleAnnotation().annotationClass().equals(ProducerModule.class);
-    }
-
-    @Override
-    boolean isRealComponent() {
-      return false;
-    }
-
-    @Override
-    ImmutableList<AnnotationValue> dependencyValues() {
-      return ImmutableList.of();
-    }
-
-    @Override
-    ImmutableList<AnnotationValue> moduleValues() {
-      return moduleAnnotation().includesAsAnnotationValues();
-    }
-
-    @Override
-    @Memoized
-    ImmutableList<TypeMirror> moduleTypes() {
-      return super.moduleTypes();
-    }
-
-    @Override
-    @Memoized
-    ImmutableSet<TypeElement> modules() {
-      return super.modules();
-    }
-
-    abstract ModuleAnnotation moduleAnnotation();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentBindingExpressions.java b/java/dagger/internal/codegen/ComponentBindingExpressions.java
deleted file mode 100644
index 37cf1e8..0000000
--- a/java/dagger/internal/codegen/ComponentBindingExpressions.java
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * Copyright (C) 2016 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.Verify.verify;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.BindingType.MEMBERS_INJECTION;
-import static dagger.internal.codegen.DelegateBindingExpression.isBindsScopeStrongerThanDependencyScope;
-import static dagger.internal.codegen.MemberSelect.staticFactoryCreation;
-import static dagger.internal.codegen.RequestKinds.isDerivedFromProvider;
-import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.DOUBLE_CHECK;
-import static dagger.internal.codegen.javapoet.TypeNames.SINGLE_CHECK;
-import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible;
-import static dagger.internal.codegen.langmodel.Accessibility.isRawTypePubliclyAccessible;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static dagger.model.BindingKind.DELEGATE;
-import static dagger.model.BindingKind.MULTIBOUND_MAP;
-import static dagger.model.BindingKind.MULTIBOUND_SET;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.MethodBindingExpression.MethodImplementationStrategy;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.RequestKind;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.type.TypeMirror;
-
-/** A central repository of code expressions used to access any binding available to a component. */
-@PerComponentImplementation
-final class ComponentBindingExpressions {
-  // TODO(dpb,ronshapiro): refactor this and ComponentRequirementExpressions into a
-  // HierarchicalComponentMap<K, V>, or perhaps this use a flattened ImmutableMap, built from its
-  // parents? If so, maybe make BindingExpression.Factory create it.
-
-  private final Optional<ComponentBindingExpressions> parent;
-  private final BindingGraph graph;
-  private final ComponentImplementation componentImplementation;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-  private final OptionalFactories optionalFactories;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final SourceVersion sourceVersion;
-  private final CompilerOptions compilerOptions;
-  private final MembersInjectionMethods membersInjectionMethods;
-  private final InnerSwitchingProviders innerSwitchingProviders;
-  private final ModifiableBindingExpressions modifiableBindingExpressions;
-  private final Map<BindingRequest, BindingExpression> expressions = new HashMap<>();
-
-  @Inject
-  ComponentBindingExpressions(
-      @ParentComponent Optional<ComponentBindingExpressions> parent,
-      BindingGraph graph,
-      ComponentImplementation componentImplementation,
-      ComponentRequirementExpressions componentRequirementExpressions,
-      OptionalFactories optionalFactories,
-      DaggerTypes types,
-      DaggerElements elements,
-      SourceVersion sourceVersion,
-      @GenerationCompilerOptions CompilerOptions compilerOptions) {
-    this.parent = parent;
-    this.graph = graph;
-    this.componentImplementation = componentImplementation;
-    this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions);
-    this.optionalFactories = checkNotNull(optionalFactories);
-    this.types = checkNotNull(types);
-    this.elements = checkNotNull(elements);
-    this.sourceVersion = checkNotNull(sourceVersion);
-    this.compilerOptions = checkNotNull(compilerOptions);
-    this.membersInjectionMethods =
-        new MembersInjectionMethods(componentImplementation, this, graph, elements, types);
-    this.innerSwitchingProviders =
-        new InnerSwitchingProviders(componentImplementation, this, types);
-    this.modifiableBindingExpressions =
-        new ModifiableBindingExpressions(
-            parent.map(cbe -> cbe.modifiableBindingExpressions),
-            this,
-            graph,
-            componentImplementation,
-            compilerOptions,
-            types);
-  }
-
-  /* Returns the {@link ModifiableBindingExpressions} for this component. */
-  ModifiableBindingExpressions modifiableBindingExpressions() {
-    return modifiableBindingExpressions;
-  }
-
-  /**
-   * Returns an expression that evaluates to the value of a binding request for a binding owned by
-   * this component or an ancestor.
-   *
-   * @param requestingClass the class that will contain the expression
-   * @throws IllegalStateException if there is no binding expression that satisfies the request
-   */
-  Expression getDependencyExpression(BindingRequest request, ClassName requestingClass) {
-    return getBindingExpression(request).getDependencyExpression(requestingClass);
-  }
-
-  /**
-   * Equivalent to {@link #getDependencyExpression(BindingRequest, ClassName)} that is used only
-   * when the request is for implementation of a component method.
-   *
-   * @throws IllegalStateException if there is no binding expression that satisfies the request
-   */
-  Expression getDependencyExpressionForComponentMethod(
-      BindingRequest request,
-      ComponentMethodDescriptor componentMethod,
-      ComponentImplementation componentImplementation) {
-    return getBindingExpression(request)
-        .getDependencyExpressionForComponentMethod(componentMethod, componentImplementation);
-  }
-
-  /**
-   * Returns the {@link CodeBlock} for the method arguments used with the factory {@code create()}
-   * method for the given {@link ContributionBinding binding}.
-   */
-  CodeBlock getCreateMethodArgumentsCodeBlock(ContributionBinding binding) {
-    return makeParametersCodeBlock(getCreateMethodArgumentsCodeBlocks(binding));
-  }
-
-  private ImmutableList<CodeBlock> getCreateMethodArgumentsCodeBlocks(ContributionBinding binding) {
-    ImmutableList.Builder<CodeBlock> arguments = ImmutableList.builder();
-
-    if (binding.requiresModuleInstance()) {
-      arguments.add(
-          componentRequirementExpressions.getExpressionDuringInitialization(
-              ComponentRequirement.forModule(binding.contributingModule().get().asType()),
-              componentImplementation.name()));
-    }
-
-    binding.frameworkDependencies().stream()
-        .map(BindingRequest::bindingRequest)
-        .map(request -> getDependencyExpression(request, componentImplementation.name()))
-        .map(Expression::codeBlock)
-        .forEach(arguments::add);
-
-    return arguments.build();
-  }
-
-  /**
-   * Returns an expression that evaluates to the value of a dependency request, for passing to a
-   * binding method, an {@code @Inject}-annotated constructor or member, or a proxy for one.
-   *
-   * <p>If the method is a generated static {@link InjectionMethods injection method}, each
-   * parameter will be {@link Object} if the dependency's raw type is inaccessible. If that is the
-   * case for this dependency, the returned expression will use a cast to evaluate to the raw type.
-   *
-   * @param requestingClass the class that will contain the expression
-   */
-  Expression getDependencyArgumentExpression(
-      DependencyRequest dependencyRequest, ClassName requestingClass) {
-
-    TypeMirror dependencyType = dependencyRequest.key().type();
-    BindingRequest bindingRequest = bindingRequest(dependencyRequest);
-    Expression dependencyExpression = getDependencyExpression(bindingRequest, requestingClass);
-
-    if (compilerOptions.aheadOfTimeSubcomponents()) {
-      TypeMirror requestedType =
-          bindingRequest.requestedType(dependencyRequest.key().type(), types);
-      // If dependencyExpression.type() has been erased to it's publicly accessible type in AOT,
-      // we must sometimes cast the expression so that it is usable in the current component. To do
-      // so, we check that without the cast the assignment would fail, that argument to this proxy
-      // method erased the type, and that the raw type of the requested type is actually accessible
-      // in the current class so that the cast is valid.
-      if (!types.isAssignable(dependencyExpression.type(), requestedType)
-          && !isRawTypePubliclyAccessible(requestedType)
-          && isRawTypeAccessible(requestedType, requestingClass.packageName())) {
-        return dependencyExpression.castTo(types.erasure(requestedType));
-      }
-    }
-
-    if (dependencyRequest.kind().equals(RequestKind.INSTANCE)
-        && !isTypeAccessibleFrom(dependencyType, requestingClass.packageName())
-        && isRawTypeAccessible(dependencyType, requestingClass.packageName())) {
-      return dependencyExpression.castTo(types.erasure(dependencyType));
-    }
-
-    return dependencyExpression;
-  }
-
-  /** Returns the implementation of a component method. */
-  MethodSpec getComponentMethod(ComponentMethodDescriptor componentMethod) {
-    checkArgument(componentMethod.dependencyRequest().isPresent());
-    BindingRequest request = bindingRequest(componentMethod.dependencyRequest().get());
-    MethodSpec.Builder method =
-        MethodSpec.overriding(
-            componentMethod.methodElement(),
-            MoreTypes.asDeclared(graph.componentTypeElement().asType()),
-            types);
-    // Even though this is not used if the method is abstract, we need to invoke the binding
-    // expression in order for the side of effect of the method being added to the
-    // ComponentImplementation
-    CodeBlock methodBody =
-        getBindingExpression(request)
-            .getComponentMethodImplementation(componentMethod, componentImplementation);
-    if (!componentImplementation.superclassImplementation().isPresent()
-        && !modifiableBindingExpressions
-            .getModifiableBindingType(request)
-            .hasBaseClassImplementation()
-        && !componentImplementation.getModifiableBindingMethod(request).isPresent()) {
-      return method.addModifiers(ABSTRACT).build();
-    }
-    return method.addCode(methodBody).build();
-  }
-
-  /** Returns the {@link BindingExpression} for the given {@link BindingRequest}. */
-  BindingExpression getBindingExpression(BindingRequest request) {
-    if (expressions.containsKey(request)) {
-      return expressions.get(request);
-    }
-    Optional<BindingExpression> expression =
-        modifiableBindingExpressions.maybeCreateModifiableBindingExpression(request);
-    if (!expression.isPresent()) {
-      ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-      if (resolvedBindings != null
-          && !resolvedBindings.bindingsOwnedBy(graph.componentDescriptor()).isEmpty()) {
-        expression = Optional.of(createBindingExpression(resolvedBindings, request));
-      }
-    }
-    if (!expression.isPresent()
-        && compilerOptions.aheadOfTimeSubcomponents()
-        && request.requestKind().isPresent()
-        && isDerivedFromProvider(request.requestKind().get())) {
-      RequestKind requestKind = request.requestKind().get();
-      expression =
-          Optional.of(
-              new DerivedFromFrameworkInstanceBindingExpression(
-                  request.key(), FrameworkType.PROVIDER, requestKind, this, types));
-    }
-
-    if (expression.isPresent()) {
-      expressions.put(request, expression.get());
-      return expression.get();
-    }
-    checkArgument(parent.isPresent(), "no expression found for %s", request);
-    return parent.get().getBindingExpression(request);
-  }
-
-  /** Creates a binding expression. */
-  BindingExpression createBindingExpression(
-      ResolvedBindings resolvedBindings, BindingRequest request) {
-    switch (resolvedBindings.bindingType()) {
-      case MEMBERS_INJECTION:
-        checkArgument(request.isRequestKind(RequestKind.MEMBERS_INJECTION));
-        return new MembersInjectionBindingExpression(resolvedBindings, membersInjectionMethods);
-
-      case PROVISION:
-        return provisionBindingExpression(resolvedBindings, request);
-
-      case PRODUCTION:
-        return productionBindingExpression(resolvedBindings, request);
-    }
-    throw new AssertionError(resolvedBindings);
-  }
-
-  /**
-   * Returns a binding expression that uses a {@link javax.inject.Provider} for provision bindings
-   * or a {@link dagger.producers.Producer} for production bindings.
-   */
-  private BindingExpression frameworkInstanceBindingExpression(ResolvedBindings resolvedBindings) {
-    // TODO(user): Consider merging the static factory creation logic into CreationExpressions?
-    Optional<MemberSelect> staticMethod =
-        useStaticFactoryCreation(resolvedBindings.contributionBinding())
-            ? staticFactoryCreation(resolvedBindings)
-            : Optional.empty();
-    FrameworkInstanceCreationExpression frameworkInstanceCreationExpression =
-        resolvedBindings.scope().isPresent()
-            ? scope(resolvedBindings, frameworkInstanceCreationExpression(resolvedBindings))
-            : frameworkInstanceCreationExpression(resolvedBindings);
-    FrameworkInstanceSupplier frameworkInstanceSupplier =
-        staticMethod.isPresent()
-            ? staticMethod::get
-            : new FrameworkFieldInitializer(
-                componentImplementation, resolvedBindings, frameworkInstanceCreationExpression);
-
-    switch (resolvedBindings.bindingType()) {
-      case PROVISION:
-        return new ProviderInstanceBindingExpression(
-            resolvedBindings, frameworkInstanceSupplier, types, elements);
-      case PRODUCTION:
-        return new ProducerNodeInstanceBindingExpression(
-            resolvedBindings, frameworkInstanceSupplier, types, elements, componentImplementation);
-      default:
-        throw new AssertionError("invalid binding type: " + resolvedBindings.bindingType());
-    }
-  }
-
-  private FrameworkInstanceCreationExpression scope(
-      ResolvedBindings resolvedBindings, FrameworkInstanceCreationExpression unscoped) {
-    return () ->
-        CodeBlock.of(
-            "$T.provider($L)",
-            resolvedBindings.scope().get().isReusable() ? SINGLE_CHECK : DOUBLE_CHECK,
-            unscoped.creationExpression());
-  }
-
-  /**
-   * Returns a creation expression for a {@link javax.inject.Provider} for provision bindings or a
-   * {@link dagger.producers.Producer} for production bindings.
-   */
-  private FrameworkInstanceCreationExpression frameworkInstanceCreationExpression(
-      ResolvedBindings resolvedBindings) {
-    checkArgument(!resolvedBindings.bindingType().equals(MEMBERS_INJECTION));
-    ContributionBinding binding = resolvedBindings.contributionBinding();
-    switch (binding.kind()) {
-      case COMPONENT:
-        // The cast can be removed when we drop java 7 source support
-        return new InstanceFactoryCreationExpression(
-            () -> CodeBlock.of("($T) this", binding.key().type()));
-
-      case BOUND_INSTANCE:
-        return instanceFactoryCreationExpression(
-            binding, ComponentRequirement.forBoundInstance(binding));
-
-      case COMPONENT_DEPENDENCY:
-        return instanceFactoryCreationExpression(
-            binding, ComponentRequirement.forDependency(binding.key().type()));
-
-      case COMPONENT_PROVISION:
-        return new DependencyMethodProviderCreationExpression(
-            binding,
-            componentImplementation,
-            componentRequirementExpressions,
-            compilerOptions,
-            graph);
-
-      case SUBCOMPONENT_CREATOR:
-        return new AnonymousProviderCreationExpression(
-            binding, this, componentImplementation.name());
-
-      case INJECTION:
-      case PROVISION:
-        return new InjectionOrProvisionProviderCreationExpression(binding, this);
-
-      case COMPONENT_PRODUCTION:
-        return new DependencyMethodProducerCreationExpression(
-            binding, componentImplementation, componentRequirementExpressions, graph);
-
-      case PRODUCTION:
-        return new ProducerCreationExpression(binding, this);
-
-      case MULTIBOUND_SET:
-        return new SetFactoryCreationExpression(binding, componentImplementation, this, graph);
-
-      case MULTIBOUND_MAP:
-        return new MapFactoryCreationExpression(
-            binding, componentImplementation, this, graph, elements);
-
-      case DELEGATE:
-        return new DelegatingFrameworkInstanceCreationExpression(
-            binding, componentImplementation, this);
-
-      case OPTIONAL:
-        return new OptionalFactoryInstanceCreationExpression(
-            optionalFactories, binding, componentImplementation, this);
-
-      case MEMBERS_INJECTOR:
-        return new MembersInjectorProviderCreationExpression((ProvisionBinding) binding, this);
-
-      default:
-        throw new AssertionError(binding);
-    }
-  }
-
-  private InstanceFactoryCreationExpression instanceFactoryCreationExpression(
-      ContributionBinding binding, ComponentRequirement componentRequirement) {
-    return new InstanceFactoryCreationExpression(
-        binding.nullableType().isPresent(),
-        () ->
-            componentRequirementExpressions.getExpressionDuringInitialization(
-                componentRequirement, componentImplementation.name()));
-  }
-
-  /** Returns a binding expression for a provision binding. */
-  private BindingExpression provisionBindingExpression(
-      ResolvedBindings resolvedBindings, BindingRequest request) {
-    if (!request.requestKind().isPresent()) {
-      verify(
-          request.frameworkType().get().equals(FrameworkType.PRODUCER_NODE),
-          "expected a PRODUCER_NODE: %s",
-          request);
-      return producerFromProviderBindingExpression(resolvedBindings);
-    }
-    RequestKind requestKind = request.requestKind().get();
-    switch (requestKind) {
-      case INSTANCE:
-        return instanceBindingExpression(resolvedBindings);
-
-      case PROVIDER:
-        return providerBindingExpression(resolvedBindings);
-
-      case LAZY:
-      case PRODUCED:
-      case PROVIDER_OF_LAZY:
-        return new DerivedFromFrameworkInstanceBindingExpression(
-            resolvedBindings.key(), FrameworkType.PROVIDER, requestKind, this, types);
-
-      case PRODUCER:
-        return producerFromProviderBindingExpression(resolvedBindings);
-
-      case FUTURE:
-        return new ImmediateFutureBindingExpression(resolvedBindings, this, types, sourceVersion);
-
-      case MEMBERS_INJECTION:
-        throw new IllegalArgumentException();
-    }
-
-    throw new AssertionError();
-  }
-
-  /** Returns a binding expression for a production binding. */
-  private BindingExpression productionBindingExpression(
-      ResolvedBindings resolvedBindings, BindingRequest request) {
-    if (request.frameworkType().isPresent()) {
-      return frameworkInstanceBindingExpression(resolvedBindings);
-    } else {
-      // If no FrameworkType is present, a RequestKind is guaranteed to be present.
-      RequestKind requestKind = request.requestKind().get();
-      return new DerivedFromFrameworkInstanceBindingExpression(
-          resolvedBindings.key(), FrameworkType.PRODUCER_NODE, requestKind, this, types);
-    }
-  }
-
-  /**
-   * Returns a binding expression for {@link RequestKind#PROVIDER} requests.
-   *
-   * <p>{@code @Binds} bindings that don't {@linkplain #needsCaching(ResolvedBindings) need to be
-   * cached} can use a {@link DelegateBindingExpression}.
-   *
-   * <p>In fastInit mode, use an {@link InnerSwitchingProviders inner switching provider} unless
-   * that provider's case statement will simply call {@code get()} on another {@link Provider} (in
-   * which case, just use that Provider directly).
-   *
-   * <p>Otherwise, return a {@link FrameworkInstanceBindingExpression}.
-   */
-  private BindingExpression providerBindingExpression(ResolvedBindings resolvedBindings) {
-    if (resolvedBindings.contributionBinding().kind().equals(DELEGATE)
-        && !needsCaching(resolvedBindings)) {
-      return new DelegateBindingExpression(
-          resolvedBindings, RequestKind.PROVIDER, this, types, elements);
-    } else if (compilerOptions.fastInit()
-        && frameworkInstanceCreationExpression(resolvedBindings).useInnerSwitchingProvider()
-        && !(instanceBindingExpression(resolvedBindings)
-            instanceof DerivedFromFrameworkInstanceBindingExpression)) {
-      return wrapInMethod(
-          resolvedBindings,
-          bindingRequest(resolvedBindings.key(), RequestKind.PROVIDER),
-          innerSwitchingProviders.newBindingExpression(resolvedBindings.contributionBinding()));
-    }
-    return frameworkInstanceBindingExpression(resolvedBindings);
-  }
-
-  /**
-   * Returns a binding expression that uses a {@link dagger.producers.Producer} field for a
-   * provision binding.
-   */
-  private FrameworkInstanceBindingExpression producerFromProviderBindingExpression(
-      ResolvedBindings resolvedBindings) {
-    checkArgument(resolvedBindings.bindingType().equals(BindingType.PROVISION));
-    return new ProducerNodeInstanceBindingExpression(
-        resolvedBindings,
-        new FrameworkFieldInitializer(
-            componentImplementation,
-            resolvedBindings,
-            new ProducerFromProviderCreationExpression(
-                resolvedBindings.contributionBinding(), componentImplementation, this)),
-        types,
-        elements,
-        componentImplementation);
-  }
-
-  /**
-   * Returns a binding expression for {@link RequestKind#INSTANCE} requests.
-   *
-   * <p>If there is a direct expression (not calling {@link Provider#get()}) we can use for an
-   * instance of this binding, return it, wrapped in a method if the binding {@linkplain
-   * #needsCaching(ResolvedBindings) needs to be cached} or the expression has dependencies.
-   *
-   * <p>In fastInit mode, we can use direct expressions unless the binding needs to be cached.
-   */
-  private BindingExpression instanceBindingExpression(ResolvedBindings resolvedBindings) {
-    Optional<BindingExpression> maybeDirectInstanceExpression =
-        unscopedDirectInstanceExpression(resolvedBindings);
-    if (canUseDirectInstanceExpression(resolvedBindings)
-        && maybeDirectInstanceExpression.isPresent()) {
-      BindingExpression directInstanceExpression = maybeDirectInstanceExpression.get();
-      return directInstanceExpression.requiresMethodEncapsulation()
-              || needsCaching(resolvedBindings)
-          ? wrapInMethod(
-              resolvedBindings,
-              bindingRequest(resolvedBindings.key(), RequestKind.INSTANCE),
-              directInstanceExpression)
-          : directInstanceExpression;
-    }
-    return new DerivedFromFrameworkInstanceBindingExpression(
-        resolvedBindings.key(), FrameworkType.PROVIDER, RequestKind.INSTANCE, this, types);
-  }
-
-  /**
-   * Returns an unscoped binding expression for an {@link RequestKind#INSTANCE} that does not call
-   * {@code get()} on its provider, if there is one.
-   */
-  private Optional<BindingExpression> unscopedDirectInstanceExpression(
-      ResolvedBindings resolvedBindings) {
-    switch (resolvedBindings.contributionBinding().kind()) {
-      case DELEGATE:
-        return Optional.of(
-            new DelegateBindingExpression(
-                resolvedBindings, RequestKind.INSTANCE, this, types, elements));
-
-      case COMPONENT:
-        return Optional.of(
-            new ComponentInstanceBindingExpression(
-                resolvedBindings, componentImplementation.name()));
-
-      case COMPONENT_DEPENDENCY:
-        return Optional.of(
-            new ComponentRequirementBindingExpression(
-                resolvedBindings,
-                ComponentRequirement.forDependency(resolvedBindings.key().type()),
-                componentRequirementExpressions));
-
-      case COMPONENT_PROVISION:
-        return Optional.of(
-            new ComponentProvisionBindingExpression(
-                resolvedBindings, graph, componentRequirementExpressions, compilerOptions));
-
-      case SUBCOMPONENT_CREATOR:
-        return Optional.of(
-            new SubcomponentCreatorBindingExpression(
-                resolvedBindings,
-                componentImplementation.getSubcomponentCreatorSimpleName(resolvedBindings.key())));
-
-      case MULTIBOUND_SET:
-        return Optional.of(
-            new SetBindingExpression(
-                resolvedBindings, componentImplementation, graph, this, types, elements));
-
-      case MULTIBOUND_MAP:
-        return Optional.of(
-            new MapBindingExpression(
-                resolvedBindings, componentImplementation, graph, this, types, elements));
-
-      case OPTIONAL:
-        return Optional.of(
-            new OptionalBindingExpression(resolvedBindings, this, types, sourceVersion));
-
-      case BOUND_INSTANCE:
-        return Optional.of(
-            new ComponentRequirementBindingExpression(
-                resolvedBindings,
-                ComponentRequirement.forBoundInstance(resolvedBindings.contributionBinding()),
-                componentRequirementExpressions));
-
-      case INJECTION:
-      case PROVISION:
-        return Optional.of(
-            new SimpleMethodBindingExpression(
-                resolvedBindings,
-                compilerOptions,
-                this,
-                membersInjectionMethods,
-                componentRequirementExpressions,
-                types,
-                elements,
-                sourceVersion));
-
-      case MEMBERS_INJECTOR:
-        return Optional.empty();
-
-      case MEMBERS_INJECTION:
-      case COMPONENT_PRODUCTION:
-      case PRODUCTION:
-        throw new IllegalArgumentException(
-            resolvedBindings.contributionBinding().kind().toString());
-    }
-    throw new AssertionError();
-  }
-
-  /**
-   * Returns {@code true} if the binding should use the static factory creation strategy.
-   *
-   * <p>In default mode, we always use the static factory creation strategy. In fastInit mode, we
-   * prefer to use a SwitchingProvider instead of static factories in order to reduce class loading;
-   * however, we allow static factories that can reused across multiple bindings, e.g. {@code
-   * MapFactory} or {@code SetFactory}.
-   */
-  private boolean useStaticFactoryCreation(ContributionBinding binding) {
-    return !compilerOptions.fastInit()
-        || binding.kind().equals(MULTIBOUND_MAP)
-        || binding.kind().equals(MULTIBOUND_SET);
-  }
-
-  /**
-   * Returns {@code true} if we can use a direct (not {@code Provider.get()}) expression for this
-   * binding. If the binding doesn't {@linkplain #needsCaching(ResolvedBindings) need to be cached},
-   * we can.
-   *
-   * <p>In fastInit mode, we can use a direct expression even if the binding {@linkplain
-   * #needsCaching(ResolvedBindings) needs to be cached}.
-   */
-  private boolean canUseDirectInstanceExpression(ResolvedBindings resolvedBindings) {
-    return !needsCaching(resolvedBindings) || compilerOptions.fastInit();
-  }
-
-  /**
-   * Returns a binding expression that uses a given one as the body of a method that users call. If
-   * a component provision method matches it, it will be the method implemented. If it does not
-   * match a component provision method and the binding is modifiable, then a new public modifiable
-   * binding method will be written. If the binding doesn't match a component method and is not
-   * modifiable, then a new private method will be written.
-   */
-  BindingExpression wrapInMethod(
-      ResolvedBindings resolvedBindings,
-      BindingRequest request,
-      BindingExpression bindingExpression) {
-    // If we've already wrapped the expression, then use the delegate.
-    if (bindingExpression instanceof MethodBindingExpression) {
-      return bindingExpression;
-    }
-
-    MethodImplementationStrategy methodImplementationStrategy =
-        methodImplementationStrategy(resolvedBindings, request);
-    Optional<ComponentMethodDescriptor> matchingComponentMethod =
-        graph.componentDescriptor().firstMatchingComponentMethod(request);
-
-    if (modifiableBindingExpressions.getModifiableBindingType(request).isModifiable()
-        && (componentImplementation.superclassImplementation().isPresent()
-            || !matchingComponentMethod.isPresent())) {
-      return modifiableBindingExpressions.wrapInModifiableMethodBindingExpression(
-          request, resolvedBindings, methodImplementationStrategy, bindingExpression);
-    } else if (matchingComponentMethod.isPresent()) {
-      ComponentMethodDescriptor componentMethod = matchingComponentMethod.get();
-      return new ComponentMethodBindingExpression(
-          request,
-          resolvedBindings,
-          methodImplementationStrategy,
-          bindingExpression,
-          componentImplementation,
-          componentMethod,
-          types);
-    } else {
-      return new PrivateMethodBindingExpression(
-          request,
-          resolvedBindings,
-          methodImplementationStrategy,
-          bindingExpression,
-          componentImplementation,
-          types);
-    }
-  }
-
-  private MethodImplementationStrategy methodImplementationStrategy(
-      ResolvedBindings resolvedBindings, BindingRequest request) {
-    if (compilerOptions.fastInit()) {
-      if (request.isRequestKind(RequestKind.PROVIDER)) {
-        return MethodImplementationStrategy.SINGLE_CHECK;
-      } else if (request.isRequestKind(RequestKind.INSTANCE) && needsCaching(resolvedBindings)) {
-        return resolvedBindings.scope().get().isReusable()
-            ? MethodImplementationStrategy.SINGLE_CHECK
-            : MethodImplementationStrategy.DOUBLE_CHECK;
-      }
-    }
-    return MethodImplementationStrategy.SIMPLE;
-  }
-
-  /**
-   * Returns {@code true} if the component needs to make sure the provided value is cached.
-   *
-   * <p>The component needs to cache the value for scoped bindings except for {@code @Binds}
-   * bindings whose scope is no stronger than their delegate's.
-   */
-  private boolean needsCaching(ResolvedBindings resolvedBindings) {
-    if (!resolvedBindings.scope().isPresent()) {
-      return false;
-    }
-    if (resolvedBindings.contributionBinding().kind().equals(DELEGATE)) {
-      return isBindsScopeStrongerThanDependencyScope(resolvedBindings, graph);
-    }
-    return true;
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorAnnotation.java b/java/dagger/internal/codegen/ComponentCreatorAnnotation.java
deleted file mode 100644
index 31bbfab..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorAnnotation.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2019 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.Ascii.toUpperCase;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.valuesOf;
-import static java.util.stream.Collectors.mapping;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.Component;
-import dagger.Subcomponent;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Annotation;
-import java.util.stream.Collector;
-import java.util.stream.Stream;
-import javax.lang.model.element.TypeElement;
-
-/** Simple representation of a component creator annotation type. */
-enum ComponentCreatorAnnotation {
-  COMPONENT_BUILDER(Component.Builder.class),
-  COMPONENT_FACTORY(Component.Factory.class),
-  SUBCOMPONENT_BUILDER(Subcomponent.Builder.class),
-  SUBCOMPONENT_FACTORY(Subcomponent.Factory.class),
-  PRODUCTION_COMPONENT_BUILDER(ProductionComponent.Builder.class),
-  PRODUCTION_COMPONENT_FACTORY(ProductionComponent.Factory.class),
-  PRODUCTION_SUBCOMPONENT_BUILDER(ProductionSubcomponent.Builder.class),
-  PRODUCTION_SUBCOMPONENT_FACTORY(ProductionSubcomponent.Factory.class),
-  ;
-
-  private final Class<? extends Annotation> annotation;
-  private final ComponentCreatorKind creatorKind;
-  private final Class<? extends Annotation> componentAnnotation;
-
-  ComponentCreatorAnnotation(Class<? extends Annotation> annotation) {
-    this.annotation = annotation;
-    this.creatorKind = ComponentCreatorKind.valueOf(toUpperCase(annotation.getSimpleName()));
-    this.componentAnnotation = (Class<? extends Annotation>) annotation.getEnclosingClass();
-  }
-
-  /** The actual annotation type. */
-  Class<? extends Annotation> annotation() {
-    return annotation;
-  }
-
-  /** The component annotation type that encloses this creator annotation type. */
-  final Class<? extends Annotation> componentAnnotation() {
-    return componentAnnotation;
-  }
-
-  /** Returns {@code true} if the creator annotation is for a subcomponent. */
-  final boolean isSubcomponentCreatorAnnotation() {
-    return componentAnnotation().getSimpleName().endsWith("Subcomponent");
-  }
-
-  /**
-   * Returns {@code true} if the creator annotation is for a production component or subcomponent.
-   */
-  final boolean isProductionCreatorAnnotation() {
-    return componentAnnotation().getSimpleName().startsWith("Production");
-  }
-
-  /** The creator kind the annotation is associated with. */
-  // TODO(dpb): Remove ComponentCreatorKind.
-  ComponentCreatorKind creatorKind() {
-    return creatorKind;
-  }
-
-  @Override
-  public final String toString() {
-    return annotation().getName();
-  }
-
-  /** Returns all component creator annotations. */
-  static ImmutableSet<Class<? extends Annotation>> allCreatorAnnotations() {
-    return stream().collect(toAnnotationClasses());
-  }
-
-  /** Returns all root component creator annotations. */
-  static ImmutableSet<Class<? extends Annotation>> rootComponentCreatorAnnotations() {
-    return stream()
-        .filter(
-            componentCreatorAnnotation ->
-                !componentCreatorAnnotation.isSubcomponentCreatorAnnotation())
-        .collect(toAnnotationClasses());
-  }
-
-  /** Returns all subcomponent creator annotations. */
-  static ImmutableSet<Class<? extends Annotation>> subcomponentCreatorAnnotations() {
-    return stream()
-        .filter(
-            componentCreatorAnnotation ->
-                componentCreatorAnnotation.isSubcomponentCreatorAnnotation())
-        .collect(toAnnotationClasses());
-  }
-
-  /** Returns all production component creator annotations. */
-  static ImmutableSet<Class<? extends Annotation>> productionCreatorAnnotations() {
-    return stream()
-        .filter(
-            componentCreatorAnnotation ->
-                componentCreatorAnnotation.isProductionCreatorAnnotation())
-        .collect(toAnnotationClasses());
-  }
-
-  /** Returns the legal creator annotations for the given {@code componentAnnotation}. */
-  static ImmutableSet<Class<? extends Annotation>> creatorAnnotationsFor(
-      ComponentAnnotation componentAnnotation) {
-    return stream()
-        .filter(
-            creatorAnnotation ->
-                creatorAnnotation
-                    .componentAnnotation()
-                    .getSimpleName()
-                    .equals(componentAnnotation.simpleName()))
-        .collect(toAnnotationClasses());
-  }
-
-  /** Returns all creator annotations present on the given {@code type}. */
-  static ImmutableSet<ComponentCreatorAnnotation> getCreatorAnnotations(TypeElement type) {
-    return stream()
-        .filter(cca -> isAnnotationPresent(type, cca.annotation()))
-        .collect(toImmutableSet());
-  }
-
-  private static Stream<ComponentCreatorAnnotation> stream() {
-    return valuesOf(ComponentCreatorAnnotation.class);
-  }
-
-  private static Collector<ComponentCreatorAnnotation, ?, ImmutableSet<Class<? extends Annotation>>>
-      toAnnotationClasses() {
-    return mapping(ComponentCreatorAnnotation::annotation, toImmutableSet());
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorDescriptor.java b/java/dagger/internal/codegen/ComponentCreatorDescriptor.java
deleted file mode 100644
index f6ec7a2..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorDescriptor.java
+++ /dev/null
@@ -1,222 +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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.auto.common.MoreTypes.asTypeElement;
-import static com.google.common.base.Verify.verify;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.getCreatorAnnotations;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import dagger.BindsInstance;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import java.util.List;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A descriptor for a component <i>creator</i> type: that is, a type annotated with
- * {@code @Component.Builder} (or one of the corresponding production or subcomponent versions).
- */
-@AutoValue
-abstract class ComponentCreatorDescriptor {
-
-  /** Returns the annotation marking this creator. */
-  abstract ComponentCreatorAnnotation annotation();
-
-  /** The kind of this creator. */
-  final ComponentCreatorKind kind() {
-    return annotation().creatorKind();
-  }
-
-  /** The annotated creator type. */
-  abstract TypeElement typeElement();
-
-  /** The method that creates and returns a component instance. */
-  abstract ExecutableElement factoryMethod();
-
-  /**
-   * Multimap of component requirements to setter methods that set that requirement.
-   *
-   * <p>In a valid creator, there will be exactly one element per component requirement, so this
-   * method should only be called when validating the descriptor.
-   */
-  abstract ImmutableSetMultimap<ComponentRequirement, ExecutableElement> unvalidatedSetterMethods();
-
-  /**
-   * Multimap of component requirements to factory method parameters that set that requirement.
-   *
-   * <p>In a valid creator, there will be exactly one element per component requirement, so this
-   * method should only be called when validating the descriptor.
-   */
-  abstract ImmutableSetMultimap<ComponentRequirement, VariableElement>
-      unvalidatedFactoryParameters();
-
-  /**
-   * Multimap of component requirements to elements (methods or parameters) that set that
-   * requirement.
-   *
-   * <p>In a valid creator, there will be exactly one element per component requirement, so this
-   * method should only be called when validating the descriptor.
-   */
-  final ImmutableSetMultimap<ComponentRequirement, Element> unvalidatedRequirementElements() {
-    // ComponentCreatorValidator ensures that there are either setter methods or factory method
-    // parameters, but not both, so we can cheat a little here since we know that only one of
-    // the two multimaps will be non-empty.
-    return ImmutableSetMultimap.copyOf( // no actual copy
-        unvalidatedSetterMethods().isEmpty()
-            ? unvalidatedFactoryParameters()
-            : unvalidatedSetterMethods());
-  }
-
-  /**
-   * Map of component requirements to elements (setter methods or factory method parameters) that
-   * set them.
-   */
-  @Memoized
-  ImmutableMap<ComponentRequirement, Element> requirementElements() {
-    return flatten(unvalidatedRequirementElements());
-  }
-
-  /** Map of component requirements to setter methods for those requirements. */
-  @Memoized
-  ImmutableMap<ComponentRequirement, ExecutableElement> setterMethods() {
-    return flatten(unvalidatedSetterMethods());
-  }
-
-  /** Map of component requirements to factory method parameters for those requirements. */
-  @Memoized
-  ImmutableMap<ComponentRequirement, VariableElement> factoryParameters() {
-    return flatten(unvalidatedFactoryParameters());
-  }
-
-  private static <K, V> ImmutableMap<K, V> flatten(Multimap<K, V> multimap) {
-    return ImmutableMap.copyOf(
-        Maps.transformValues(multimap.asMap(), values -> getOnlyElement(values)));
-  }
-
-  /** Returns the set of component requirements this creator allows the user to set. */
-  final ImmutableSet<ComponentRequirement> userSettableRequirements() {
-    // Note: they should have been validated at the point this is used, so this set is valid.
-    return unvalidatedRequirementElements().keySet();
-  }
-
-  /** Returns the set of requirements for modules and component dependencies for this creator. */
-  final ImmutableSet<ComponentRequirement> moduleAndDependencyRequirements() {
-    return userSettableRequirements().stream()
-        .filter(requirement -> !requirement.isBoundInstance())
-        .collect(toImmutableSet());
-  }
-
-  /** Returns the set of bound instance requirements for this creator. */
-  final ImmutableSet<ComponentRequirement> boundInstanceRequirements() {
-    return userSettableRequirements().stream()
-        .filter(ComponentRequirement::isBoundInstance)
-        .collect(toImmutableSet());
-  }
-
-  /** Returns the element in this creator that sets the given {@code requirement}. */
-  final Element elementForRequirement(ComponentRequirement requirement) {
-    return requirementElements().get(requirement);
-  }
-
-  /** Creates a new {@link ComponentCreatorDescriptor} for the given creator {@code type}. */
-  static ComponentCreatorDescriptor create(
-      DeclaredType type,
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestFactory dependencyRequestFactory) {
-    TypeElement typeElement = asTypeElement(type);
-    TypeMirror componentType = typeElement.getEnclosingElement().asType();
-
-    ImmutableSetMultimap.Builder<ComponentRequirement, ExecutableElement> setterMethods =
-        ImmutableSetMultimap.builder();
-
-    ExecutableElement factoryMethod = null;
-    for (ExecutableElement method : elements.getUnimplementedMethods(typeElement)) {
-      ExecutableType resolvedMethodType = MoreTypes.asExecutable(types.asMemberOf(type, method));
-
-      if (types.isSubtype(componentType, resolvedMethodType.getReturnType())) {
-        factoryMethod = method;
-      } else {
-        VariableElement parameter = getOnlyElement(method.getParameters());
-        TypeMirror parameterType = getOnlyElement(resolvedMethodType.getParameterTypes());
-        setterMethods.put(
-            requirement(method, parameter, parameterType, dependencyRequestFactory, method),
-            method);
-      }
-    }
-    verify(factoryMethod != null); // validation should have ensured this.
-
-    ImmutableSetMultimap.Builder<ComponentRequirement, VariableElement> factoryParameters =
-        ImmutableSetMultimap.builder();
-
-    ExecutableType resolvedFactoryMethodType =
-        MoreTypes.asExecutable(types.asMemberOf(type, factoryMethod));
-    List<? extends VariableElement> parameters = factoryMethod.getParameters();
-    List<? extends TypeMirror> parameterTypes = resolvedFactoryMethodType.getParameterTypes();
-    for (int i = 0; i < parameters.size(); i++) {
-      VariableElement parameter = parameters.get(i);
-      TypeMirror parameterType = parameterTypes.get(i);
-      factoryParameters.put(
-          requirement(factoryMethod, parameter, parameterType, dependencyRequestFactory, parameter),
-          parameter);
-    }
-
-    // Validation should have ensured exactly one creator annotation is present on the type.
-    ComponentCreatorAnnotation annotation = getOnlyElement(getCreatorAnnotations(typeElement));
-    return new AutoValue_ComponentCreatorDescriptor(
-        annotation, typeElement, factoryMethod, setterMethods.build(), factoryParameters.build());
-  }
-
-  private static ComponentRequirement requirement(
-      ExecutableElement method,
-      VariableElement parameter,
-      TypeMirror type,
-      DependencyRequestFactory dependencyRequestFactory,
-      Element elementForVariableName) {
-    if (isAnnotationPresent(method, BindsInstance.class)
-        || isAnnotationPresent(parameter, BindsInstance.class)) {
-      DependencyRequest request =
-          dependencyRequestFactory.forRequiredResolvedVariable(parameter, type);
-      String variableName = elementForVariableName.getSimpleName().toString();
-      return ComponentRequirement.forBoundInstance(
-          request.key(), request.isNullable(), variableName);
-    }
-
-    return moduleAnnotation(asTypeElement(type)).isPresent()
-        ? ComponentRequirement.forModule(type)
-        : ComponentRequirement.forDependency(type);
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorImplementation.java b/java/dagger/internal/codegen/ComponentCreatorImplementation.java
deleted file mode 100644
index a5eb680..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorImplementation.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableMap;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.TypeSpec;
-
-/** The implementation of a component creator type. */
-@AutoValue
-abstract class ComponentCreatorImplementation {
-
-  /** Creates a new {@link ComponentCreatorImplementation}. */
-  static ComponentCreatorImplementation create(
-      TypeSpec spec,
-      ClassName name,
-      ImmutableMap<ComponentRequirement, FieldSpec> fields) {
-    return new AutoValue_ComponentCreatorImplementation(spec, name, fields);
-  }
-
-  /** The type spec for the creator implementation. */
-  abstract TypeSpec spec();
-
-  /** The name of the creator implementation class. */
-  abstract ClassName name();
-
-  /**
-   * All fields that are present in this implementation or its supertype.
-   *
-   * <p>In the case of ahead-of-time subcomponents, not all fields will necessarily be passed to
-   * the component's constructor (because, for example, it turns out that a particular module that
-   * the creator can set is actually inherited from an ancestor module).
-   */
-  abstract ImmutableMap<ComponentRequirement, FieldSpec> fields();
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorImplementationFactory.java b/java/dagger/internal/codegen/ComponentCreatorImplementationFactory.java
deleted file mode 100644
index 4f06b90..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorImplementationFactory.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (C) 2017 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.auto.common.MoreTypes.asDeclared;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.Iterables.getOnlyElement;
-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.SourceFiles.simpleVariableName;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeSpecs.addSupertype;
-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.PROTECTED;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.Preconditions;
-import dagger.internal.codegen.ComponentRequirement.NullPolicy;
-import dagger.internal.codegen.javapoet.TypeNames;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-
-/** Factory for creating {@link ComponentCreatorImplementation} instances. */
-final class ComponentCreatorImplementationFactory {
-
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-
-  @Inject
-  ComponentCreatorImplementationFactory(DaggerElements elements, DaggerTypes types) {
-    this.elements = elements;
-    this.types = types;
-  }
-
-  /** Returns a new creator implementation for the given component, if necessary. */
-  Optional<ComponentCreatorImplementation> create(
-      ComponentImplementation componentImplementation, Optional<BindingGraph> graph) {
-    if (!componentImplementation.componentDescriptor().hasCreator()) {
-      return Optional.empty();
-    }
-
-    Optional<ComponentCreatorDescriptor> creatorDescriptor =
-        componentImplementation.componentDescriptor().creatorDescriptor();
-
-    if (componentImplementation.isAbstract()
-        && (hasNoSetterMethods(creatorDescriptor)
-            || componentImplementation.superclassImplementation().isPresent())) {
-      // 1. Factory-like creators (those with no setter methods) are only generated in concrete
-      //    components, because they only have a factory method and the factory method must call
-      //    a concrete component's constructor.
-      // 2. The component builder in ahead-of-time mode is generated with the base subcomponent
-      //    implementation, with the exception of the build method since that requires invoking the
-      //    constructor of a concrete component implementation. Intermediate component
-      //    implementations, because they still can't invoke the eventual constructor and have no
-      //    additional extensions to the builder, can ignore generating a builder implementation.
-      return Optional.empty();
-    }
-
-    Builder builder =
-        creatorDescriptor.isPresent()
-            ? new BuilderForCreatorDescriptor(
-                componentImplementation, creatorDescriptor.get(), graph)
-            : new BuilderForGeneratedRootComponentBuilder(componentImplementation);
-    return Optional.of(builder.build());
-  }
-
-  private static boolean hasNoSetterMethods(
-      Optional<ComponentCreatorDescriptor> creatorDescriptor) {
-    return creatorDescriptor.filter(descriptor -> descriptor.setterMethods().isEmpty()).isPresent();
-  }
-
-  /** Base class for building a creator implementation. */
-  private abstract class Builder {
-    final ComponentImplementation componentImplementation;
-    final ClassName className;
-    final TypeSpec.Builder classBuilder;
-
-    private ImmutableMap<ComponentRequirement, FieldSpec> fields;
-
-    Builder(ComponentImplementation componentImplementation) {
-      this.componentImplementation = componentImplementation;
-      this.className = componentImplementation.getCreatorName();
-      this.classBuilder = classBuilder(className);
-    }
-
-    /** Builds the {@link ComponentCreatorImplementation}. */
-    ComponentCreatorImplementation build() {
-      setModifiers();
-      setSupertype();
-      this.fields = getOrAddFields();
-      addConstructor();
-      addSetterMethods();
-      addFactoryMethod();
-      return ComponentCreatorImplementation.create(classBuilder.build(), className, fields);
-    }
-
-    /** Returns the descriptor for the component. */
-    final ComponentDescriptor componentDescriptor() {
-      return componentImplementation.componentDescriptor();
-    }
-
-    /**
-     * The set of requirements that must be passed to the component's constructor in the order
-     * they must be passed.
-     */
-    final ImmutableSet<ComponentRequirement> componentConstructorRequirements() {
-      return componentImplementation.requirements();
-    }
-
-    /** Returns the requirements that have setter methods on the creator type. */
-    abstract ImmutableSet<ComponentRequirement> setterMethods();
-
-    /**
-     * Returns the component requirements that have factory method parameters, mapped to the name
-     * for that parameter.
-     */
-    abstract ImmutableMap<ComponentRequirement, String> factoryMethodParameters();
-
-    /**
-     * The {@link ComponentRequirement}s that this creator allows users to set. Values are a status
-     * for each requirement indicating what's needed for that requirement in the implementation
-     * class currently being generated.
-     */
-    abstract ImmutableMap<ComponentRequirement, RequirementStatus> userSettableRequirements();
-
-    /**
-     * Component requirements that are both settable by the creator and needed to construct the
-     * component.
-     */
-    private Set<ComponentRequirement> neededUserSettableRequirements() {
-      return Sets.intersection(
-          userSettableRequirements().keySet(), componentConstructorRequirements());
-    }
-
-    private void setModifiers() {
-      visibility().ifPresent(classBuilder::addModifiers);
-      if (!componentImplementation.isNested()) {
-        classBuilder.addModifiers(STATIC);
-      }
-      classBuilder.addModifiers(componentImplementation.isAbstract() ? ABSTRACT : FINAL);
-    }
-
-    /** Returns the visibility modifier the generated class should have, if any. */
-    protected abstract Optional<Modifier> visibility();
-
-    /** Sets the superclass being extended or interface being implemented for this creator. */
-    protected abstract void setSupertype();
-
-    /** Adds a constructor for the creator type, if needed. */
-    protected abstract void addConstructor();
-
-    private ImmutableMap<ComponentRequirement, FieldSpec> getOrAddFields() {
-      // If a base implementation is present, any fields are already defined there and don't need to
-      // be created in this implementation.
-      return componentImplementation
-          .baseCreatorImplementation()
-          .map(ComponentCreatorImplementation::fields)
-          .orElseGet(this::addFields);
-    }
-
-    private ImmutableMap<ComponentRequirement, FieldSpec> addFields() {
-      // Fields in an abstract creator class need to be visible from subclasses.
-      Modifier modifier = componentImplementation.isAbstract() ? PROTECTED : PRIVATE;
-      UniqueNameSet fieldNames = new UniqueNameSet();
-      ImmutableMap<ComponentRequirement, FieldSpec> result =
-          Maps.toMap(
-              Sets.intersection(neededUserSettableRequirements(), setterMethods()),
-              requirement ->
-                  FieldSpec.builder(
-                          TypeName.get(requirement.type()),
-                          fieldNames.getUniqueName(requirement.variableName()),
-                          modifier)
-                      .build());
-      classBuilder.addFields(result.values());
-      return result;
-    }
-
-    private void addSetterMethods() {
-      Maps.filterKeys(userSettableRequirements(), setterMethods()::contains)
-          .forEach(
-              (requirement, status) ->
-                  createSetterMethod(requirement, status).ifPresent(classBuilder::addMethod));
-    }
-
-    /** Creates a new setter method builder, with no method body, for the given requirement. */
-    protected abstract MethodSpec.Builder setterMethodBuilder(ComponentRequirement requirement);
-
-    private Optional<MethodSpec> createSetterMethod(
-        ComponentRequirement requirement, RequirementStatus status) {
-      switch (status) {
-        case NEEDED:
-          return Optional.of(normalSetterMethod(requirement));
-        case UNNEEDED:
-          return Optional.of(noopSetterMethod(requirement));
-        case UNSETTABLE_REPEATED_MODULE:
-          return Optional.of(repeatedModuleSetterMethod(requirement));
-        case IMPLEMENTED_IN_SUPERTYPE:
-          return Optional.empty();
-      }
-      throw new AssertionError();
-    }
-
-    private MethodSpec normalSetterMethod(ComponentRequirement requirement) {
-      MethodSpec.Builder method = setterMethodBuilder(requirement);
-      ParameterSpec parameter = parameter(method.build());
-      method.addStatement(
-          "this.$N = $L",
-          fields.get(requirement),
-          requirement.nullPolicy(elements, types).equals(NullPolicy.ALLOW)
-              ? CodeBlock.of("$N", parameter)
-              : CodeBlock.of("$T.checkNotNull($N)", Preconditions.class, parameter));
-      return maybeReturnThis(method);
-    }
-
-    private MethodSpec noopSetterMethod(ComponentRequirement requirement) {
-      MethodSpec.Builder method = setterMethodBuilder(requirement);
-      ParameterSpec parameter = parameter(method.build());
-      method
-          .addAnnotation(Deprecated.class)
-          .addJavadoc(
-              "@deprecated This module is declared, but an instance is not used in the component. "
-                  + "This method is a no-op. For more, see https://dagger.dev/unused-modules.\n")
-          .addStatement("$T.checkNotNull($N)", Preconditions.class, parameter);
-      return maybeReturnThis(method);
-    }
-
-    private MethodSpec repeatedModuleSetterMethod(ComponentRequirement requirement) {
-      return setterMethodBuilder(requirement)
-          .addStatement(
-              "throw new $T($T.format($S, $T.class.getCanonicalName()))",
-              UnsupportedOperationException.class,
-              String.class,
-              "%s cannot be set because it is inherited from the enclosing component",
-              TypeNames.rawTypeName(TypeName.get(requirement.type())))
-          .build();
-    }
-
-    private ParameterSpec parameter(MethodSpec method) {
-      return getOnlyElement(method.parameters);
-    }
-
-    private MethodSpec maybeReturnThis(MethodSpec.Builder method) {
-      MethodSpec built = method.build();
-      return built.returnType.equals(TypeName.VOID)
-          ? built
-          : method.addStatement("return this").build();
-    }
-
-    private void addFactoryMethod() {
-      if (!componentImplementation.isAbstract()) {
-        classBuilder.addMethod(factoryMethod());
-      }
-    }
-
-    MethodSpec factoryMethod() {
-      MethodSpec.Builder factoryMethod = factoryMethodBuilder();
-      factoryMethod
-          .returns(ClassName.get(componentDescriptor().typeElement()))
-          .addModifiers(PUBLIC);
-
-      ImmutableMap<ComponentRequirement, String> factoryMethodParameters =
-          factoryMethodParameters();
-      userSettableRequirements()
-          .keySet()
-          .forEach(
-              requirement -> {
-                if (fields.containsKey(requirement)
-                    && componentConstructorRequirements().contains(requirement)) {
-                  // In AOT mode, there can be a field for a requirement even if the component's
-                  // constructor doesn't need it, because the base class for the creator was created
-                  // before the final graph for the component was known.
-                  FieldSpec field = fields.get(requirement);
-                  addNullHandlingForField(requirement, field, factoryMethod);
-                } else if (factoryMethodParameters.containsKey(requirement)) {
-                  String parameterName = factoryMethodParameters.get(requirement);
-                  addNullHandlingForParameter(requirement, parameterName, factoryMethod);
-                }
-              });
-      factoryMethod.addStatement(
-          "return new $T($L)",
-          componentImplementation.name(),
-          componentConstructorArgs(factoryMethodParameters));
-      return factoryMethod.build();
-    }
-
-    private void addNullHandlingForField(
-        ComponentRequirement requirement, FieldSpec field, MethodSpec.Builder factoryMethod) {
-      switch (requirement.nullPolicy(elements, types)) {
-        case NEW:
-          checkState(requirement.kind().isModule());
-          factoryMethod
-              .beginControlFlow("if ($N == null)", field)
-              .addStatement("this.$N = $L", field, newModuleInstance(requirement))
-              .endControlFlow();
-          break;
-        case THROW:
-          // TODO(cgdecker,ronshapiro): ideally this should use the key instead of a class for
-          // @BindsInstance requirements, but that's not easily proguardable.
-          factoryMethod.addStatement(
-              "$T.checkBuilderRequirement($N, $T.class)",
-              Preconditions.class,
-              field,
-              TypeNames.rawTypeName(field.type));
-          break;
-        case ALLOW:
-          break;
-      }
-    }
-
-    private void addNullHandlingForParameter(
-        ComponentRequirement requirement, String parameter, MethodSpec.Builder factoryMethod) {
-      if (!requirement.nullPolicy(elements, types).equals(NullPolicy.ALLOW)) {
-        // Factory method parameters are always required unless they are a nullable
-        // binds-instance (i.e. ALLOW)
-        factoryMethod.addStatement("$T.checkNotNull($L)", Preconditions.class, parameter);
-      }
-    }
-
-    /** Returns a builder for the creator's factory method. */
-    protected abstract MethodSpec.Builder factoryMethodBuilder();
-
-    private CodeBlock componentConstructorArgs(
-        ImmutableMap<ComponentRequirement, String> factoryMethodParameters) {
-      return componentConstructorRequirements().stream()
-          .map(
-              requirement -> {
-                if (fields.containsKey(requirement)) {
-                  return CodeBlock.of("$N", fields.get(requirement));
-                } else if (factoryMethodParameters.containsKey(requirement)) {
-                  return CodeBlock.of("$L", factoryMethodParameters.get(requirement));
-                } else {
-                  return newModuleInstance(requirement);
-                }
-              })
-          .collect(toParametersCodeBlock());
-    }
-
-    private CodeBlock newModuleInstance(ComponentRequirement requirement) {
-      checkArgument(requirement.kind().isModule()); // this should be guaranteed to be true here
-      return ModuleProxies.newModuleInstance(requirement.typeElement(), className, elements);
-    }
-  }
-
-  /** Builder for a creator type defined by a {@code ComponentCreatorDescriptor}. */
-  private final class BuilderForCreatorDescriptor extends Builder {
-    final ComponentCreatorDescriptor creatorDescriptor;
-    private final Optional<BindingGraph> graph;
-
-    BuilderForCreatorDescriptor(
-        ComponentImplementation componentImplementation,
-        ComponentCreatorDescriptor creatorDescriptor,
-        Optional<BindingGraph> graph) {
-      super(componentImplementation);
-      this.creatorDescriptor = creatorDescriptor;
-      this.graph = graph;
-    }
-
-    @Override
-    protected ImmutableMap<ComponentRequirement, RequirementStatus> userSettableRequirements() {
-      return Maps.toMap(creatorDescriptor.userSettableRequirements(), this::requirementStatus);
-    }
-
-    @Override
-    protected Optional<Modifier> visibility() {
-      if (componentImplementation.isAbstract()) {
-        // The component creator class of a top-level component implementation in ahead-of-time
-        // subcomponents mode must be public, not protected, because the creator's subclass will
-        // be a sibling of the component subclass implementation, not nested.
-        return Optional.of(componentImplementation.isNested() ? PROTECTED : PUBLIC);
-      }
-      return Optional.of(PRIVATE);
-    }
-
-    @Override
-    protected void setSupertype() {
-      if (componentImplementation.baseCreatorImplementation().isPresent()) {
-        // If an abstract base implementation for this creator exists, extend that class.
-        classBuilder.superclass(componentImplementation.baseCreatorImplementation().get().name());
-      } else {
-        addSupertype(classBuilder, creatorDescriptor.typeElement());
-      }
-    }
-
-    @Override
-    protected void addConstructor() {
-      // Just use the implicit no-arg public constructor.
-    }
-
-    @Override
-    protected ImmutableSet<ComponentRequirement> setterMethods() {
-      return ImmutableSet.copyOf(creatorDescriptor.setterMethods().keySet());
-    }
-
-    @Override
-    protected ImmutableMap<ComponentRequirement, String> factoryMethodParameters() {
-      return ImmutableMap.copyOf(
-          Maps.transformValues(
-              creatorDescriptor.factoryParameters(),
-              element -> element.getSimpleName().toString()));
-    }
-
-    private DeclaredType creatorType() {
-      return asDeclared(creatorDescriptor.typeElement().asType());
-    }
-
-    @Override
-    protected MethodSpec.Builder factoryMethodBuilder() {
-      return MethodSpec.overriding(creatorDescriptor.factoryMethod(), creatorType(), types);
-    }
-
-    private RequirementStatus requirementStatus(ComponentRequirement requirement) {
-      // In ahead-of-time subcomponents mode, all builder methods are defined at the base
-      // implementation. The only case where a method needs to be overridden is for a repeated
-      // module, which is unknown at the point when a base implementation is generated. We do this
-      // at the root for simplicity (and as an aside, repeated modules are never used in google
-      // as of 11/28/18, and thus the additional cost of including these methods at the root is
-      // negligible).
-      if (isRepeatedModule(requirement)) {
-        return RequirementStatus.UNSETTABLE_REPEATED_MODULE;
-      }
-
-      if (hasBaseCreatorImplementation()) {
-        return RequirementStatus.IMPLEMENTED_IN_SUPERTYPE;
-      }
-
-      return componentConstructorRequirements().contains(requirement)
-          ? RequirementStatus.NEEDED
-          : RequirementStatus.UNNEEDED;
-    }
-
-    /**
-     * Returns whether the given requirement is for a repeat of a module inherited from an ancestor
-     * component. This creator is not allowed to set such a module.
-     */
-    final boolean isRepeatedModule(ComponentRequirement requirement) {
-      return !componentConstructorRequirements().contains(requirement)
-          && !isOwnedModule(requirement);
-    }
-
-    /**
-     * Returns whether the given {@code requirement} is for a module type owned by the component.
-     */
-    private boolean isOwnedModule(ComponentRequirement requirement) {
-      return graph.map(g -> g.ownedModuleTypes().contains(requirement.typeElement())).orElse(true);
-    }
-
-    private boolean hasBaseCreatorImplementation() {
-      return !componentImplementation.isAbstract()
-          && componentImplementation.baseImplementation().isPresent();
-    }
-
-    @Override
-    protected MethodSpec.Builder setterMethodBuilder(ComponentRequirement requirement) {
-      ExecutableElement supertypeMethod = creatorDescriptor.setterMethods().get(requirement);
-      MethodSpec.Builder method = MethodSpec.overriding(supertypeMethod, creatorType(), types);
-      if (!supertypeMethod.getReturnType().getKind().equals(TypeKind.VOID)) {
-        // Take advantage of covariant returns so that we don't have to worry about type variables
-        method.returns(className);
-      }
-      return method;
-    }
-  }
-
-  /**
-   * Builder for a component builder class that is automatically generated for a root component that
-   * does not have its own user-defined creator type (i.e. a {@code ComponentCreatorDescriptor}).
-   */
-  private final class BuilderForGeneratedRootComponentBuilder extends Builder {
-    BuilderForGeneratedRootComponentBuilder(ComponentImplementation componentImplementation) {
-      super(componentImplementation);
-    }
-
-    @Override
-    protected ImmutableMap<ComponentRequirement, RequirementStatus> userSettableRequirements() {
-      return Maps.toMap(
-          setterMethods(),
-          requirement ->
-              componentConstructorRequirements().contains(requirement)
-                  ? RequirementStatus.NEEDED
-                  : RequirementStatus.UNNEEDED);
-    }
-
-    @Override
-    protected Optional<Modifier> visibility() {
-      return componentImplementation
-          .componentDescriptor()
-          .typeElement()
-          .getModifiers()
-          .contains(PUBLIC) ? Optional.of(PUBLIC) : Optional.empty();
-    }
-
-    @Override
-    protected void setSupertype() {
-      // There's never a supertype for a root component auto-generated builder type.
-    }
-
-    @Override
-    protected void addConstructor() {
-      classBuilder.addMethod(constructorBuilder().addModifiers(PRIVATE).build());
-    }
-
-    @Override
-    protected ImmutableSet<ComponentRequirement> setterMethods() {
-      return componentDescriptor().dependenciesAndConcreteModules();
-    }
-
-    @Override
-    protected ImmutableMap<ComponentRequirement, String> factoryMethodParameters() {
-      return ImmutableMap.of();
-    }
-
-    @Override
-    protected MethodSpec.Builder factoryMethodBuilder() {
-      return methodBuilder("build");
-    }
-
-    @Override
-    protected MethodSpec.Builder setterMethodBuilder(ComponentRequirement requirement) {
-      String name = simpleVariableName(requirement.typeElement());
-      return methodBuilder(name)
-          .addModifiers(PUBLIC)
-          .addParameter(TypeName.get(requirement.type()), name)
-          .returns(className);
-    }
-  }
-
-  /** Enumeration of statuses a component requirement may have in a creator. */
-  enum RequirementStatus {
-    /** An instance is needed to create the component. */
-    NEEDED,
-
-    /**
-     * An instance is not needed to create the component, but the requirement is for a module owned
-     * by the component. Setting the requirement is a no-op and any setter method should be marked
-     * deprecated on the generated type as a warning to the user.
-     */
-    UNNEEDED,
-
-    /**
-     * The requirement may not be set in this creator because the module it is for is already
-     * inherited from an ancestor component. Any setter method for it should throw an exception.
-     */
-    UNSETTABLE_REPEATED_MODULE,
-
-    /**
-     * The requirement is settable by the creator, but the setter method implementation already
-     * exists in a supertype.
-     */
-    IMPLEMENTED_IN_SUPERTYPE,
-    ;
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorKind.java b/java/dagger/internal/codegen/ComponentCreatorKind.java
deleted file mode 100644
index dc203de..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorKind.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 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.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-
-import com.google.common.base.Ascii;
-
-/** Enumeration of the different kinds of component creators. */
-enum ComponentCreatorKind {
-  /** {@code @Component.Builder} or one of its subcomponent/production variants. */
-  BUILDER,
-
-  /** {@code @Component.Factory} or one of its subcomponent/production variants. */
-  FACTORY,
-  ;
-
-  /** Name to use as (or as part of) a type name for a creator of this kind. */
-  String typeName() {
-    return UPPER_UNDERSCORE.to(UPPER_CAMEL, name());
-  }
-
-  /** Name to use for a component's static method returning a creator of this kind. */
-  String methodName() {
-    return Ascii.toLowerCase(name());
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentCreatorValidator.java b/java/dagger/internal/codegen/ComponentCreatorValidator.java
deleted file mode 100644
index c55dadd..0000000
--- a/java/dagger/internal/codegen/ComponentCreatorValidator.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.getCreatorAnnotations;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ObjectArrays;
-import dagger.BindsInstance;
-import dagger.internal.codegen.ErrorMessages.ComponentCreatorMessages;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.List;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-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.lang.model.util.ElementFilter;
-
-/** Validates types annotated with component creator annotations. */
-final class ComponentCreatorValidator {
-
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-
-  @Inject
-  ComponentCreatorValidator(DaggerElements elements, DaggerTypes types) {
-    this.elements = elements;
-    this.types = types;
-  }
-
-  /** Validates that the given {@code type} is potentially a valid component creator type. */
-  public ValidationReport<TypeElement> validate(TypeElement type) {
-    ValidationReport.Builder<TypeElement> report = ValidationReport.about(type);
-
-    ImmutableSet<ComponentCreatorAnnotation> creatorAnnotations = getCreatorAnnotations(type);
-    if (!validateOnlyOneCreatorAnnotation(creatorAnnotations, report)) {
-      return report.build();
-    }
-
-    // Note: there's more validation in ComponentDescriptorValidator:
-    // - to make sure the setter methods/factory parameters mirror the deps
-    // - to make sure each type or key is set by only one method or parameter
-    ElementValidator validator =
-        new ElementValidator(type, report, getOnlyElement(creatorAnnotations));
-    return validator.validate();
-  }
-
-  private boolean validateOnlyOneCreatorAnnotation(
-      ImmutableSet<ComponentCreatorAnnotation> creatorAnnotations,
-      ValidationReport.Builder<?> report) {
-    // creatorAnnotations should never be empty because this should only ever be called for
-    // types that have been found to have some creator annotation
-    if (creatorAnnotations.size() > 1) {
-      String error =
-          "May not have more than one component Factory or Builder annotation on a type"
-              + ": found "
-              + creatorAnnotations;
-      report.addError(error);
-      return false;
-    }
-
-    return true;
-  }
-
-  /**
-   * Validator for a single {@link TypeElement} that is annotated with a {@code Builder} or {@code
-   * Factory} annotation.
-   */
-  private final class ElementValidator {
-    private final TypeElement type;
-    private final Element component;
-    private final ValidationReport.Builder<TypeElement> report;
-    private final ComponentCreatorAnnotation annotation;
-    private final ComponentCreatorMessages messages;
-
-    private ElementValidator(
-        TypeElement type,
-        ValidationReport.Builder<TypeElement> report,
-        ComponentCreatorAnnotation annotation) {
-      this.type = type;
-      this.component = type.getEnclosingElement();
-      this.report = report;
-      this.annotation = annotation;
-      this.messages = ErrorMessages.creatorMessagesFor(annotation);
-    }
-
-    /** Validates the creator type. */
-    final ValidationReport<TypeElement> validate() {
-      if (!isAnnotationPresent(component, annotation.componentAnnotation())) {
-        report.addError(messages.mustBeInComponent());
-      }
-
-      // If the type isn't a class or interface, don't validate anything else since the rest of the
-      // messages will be bogus.
-      if (!validateIsClassOrInterface()) {
-        return report.build();
-      }
-
-      validateTypeRequirements();
-      switch (annotation.creatorKind()) {
-        case FACTORY:
-          validateFactory();
-          break;
-        case BUILDER:
-          validateBuilder();
-      }
-
-      return report.build();
-    }
-
-    /** Validates that the type is a class or interface type and returns true if it is. */
-    private boolean validateIsClassOrInterface() {
-      switch (type.getKind()) {
-        case CLASS:
-          validateConstructor();
-          return true;
-        case INTERFACE:
-          return true;
-        default:
-          report.addError(messages.mustBeClassOrInterface());
-      }
-      return false;
-    }
-
-    private void validateConstructor() {
-      List<? extends Element> allElements = type.getEnclosedElements();
-      List<ExecutableElement> constructors = ElementFilter.constructorsIn(allElements);
-
-      boolean valid = true;
-      if (constructors.size() != 1) {
-        valid = false;
-      } else {
-        ExecutableElement constructor = getOnlyElement(constructors);
-        valid =
-            constructor.getParameters().isEmpty() && !constructor.getModifiers().contains(PRIVATE);
-      }
-
-      if (!valid) {
-        report.addError(messages.invalidConstructor());
-      }
-    }
-
-    /** Validates basic requirements about the type that are common to both creator kinds. */
-    private void validateTypeRequirements() {
-      if (!type.getTypeParameters().isEmpty()) {
-        report.addError(messages.generics());
-      }
-
-      Set<Modifier> modifiers = type.getModifiers();
-      if (modifiers.contains(PRIVATE)) {
-        report.addError(messages.isPrivate());
-      }
-      if (!modifiers.contains(STATIC)) {
-        report.addError(messages.mustBeStatic());
-      }
-      // Note: Must be abstract, so no need to check for final.
-      if (!modifiers.contains(ABSTRACT)) {
-        report.addError(messages.mustBeAbstract());
-      }
-    }
-
-    private void validateBuilder() {
-      ExecutableElement buildMethod = null;
-      for (ExecutableElement method : elements.getUnimplementedMethods(type)) {
-        switch (method.getParameters().size()) {
-          case 0: // If this is potentially a build() method, validate it returns the correct type.
-            if (validateFactoryMethodReturnType(method)) {
-              if (buildMethod != null) {
-                // If we found more than one build-like method, fail.
-                error(
-                    method,
-                    messages.twoFactoryMethods(),
-                    messages.inheritedTwoFactoryMethods(),
-                    buildMethod);
-              }
-            }
-            // We set the buildMethod regardless of the return type to reduce error spam.
-            buildMethod = method;
-            break;
-
-          case 1: // If this correctly had one parameter, make sure the return types are valid.
-            validateSetterMethod(method);
-            break;
-
-          default: // more than one parameter
-            error(
-                method,
-                messages.setterMethodsMustTakeOneArg(),
-                messages.inheritedSetterMethodsMustTakeOneArg());
-            break;
-        }
-      }
-
-      if (buildMethod == null) {
-        report.addError(messages.missingFactoryMethod());
-      } else {
-        validateNotGeneric(buildMethod);
-      }
-    }
-
-    private void validateSetterMethod(ExecutableElement method) {
-      TypeMirror returnType = types.resolveExecutableType(method, type.asType()).getReturnType();
-      if (returnType.getKind() != TypeKind.VOID && !types.isSubtype(type.asType(), returnType)) {
-        error(
-            method,
-            messages.setterMethodsMustReturnVoidOrBuilder(),
-            messages.inheritedSetterMethodsMustReturnVoidOrBuilder());
-      }
-
-      validateNotGeneric(method);
-
-      VariableElement parameter = method.getParameters().get(0);
-
-      boolean methodIsBindsInstance = isAnnotationPresent(method, BindsInstance.class);
-      boolean parameterIsBindsInstance = isAnnotationPresent(parameter, BindsInstance.class);
-      boolean bindsInstance = methodIsBindsInstance || parameterIsBindsInstance;
-
-      if (methodIsBindsInstance && parameterIsBindsInstance) {
-        error(
-            method,
-            messages.bindsInstanceNotAllowedOnBothSetterMethodAndParameter(),
-            messages.inheritedBindsInstanceNotAllowedOnBothSetterMethodAndParameter());
-      }
-
-      if (!bindsInstance && parameter.asType().getKind().isPrimitive()) {
-        error(
-            method,
-            messages.nonBindsInstanceParametersMayNotBePrimitives(),
-            messages.inheritedNonBindsInstanceParametersMayNotBePrimitives());
-      }
-    }
-
-    private void validateFactory() {
-      ImmutableList<ExecutableElement> abstractMethods =
-          elements.getUnimplementedMethods(type).asList();
-      switch (abstractMethods.size()) {
-        case 0:
-          report.addError(messages.missingFactoryMethod());
-          return;
-        case 1:
-          break; // good
-        default:
-          error(
-              abstractMethods.get(1),
-              messages.twoFactoryMethods(),
-              messages.inheritedTwoFactoryMethods(),
-              abstractMethods.get(0));
-          return;
-      }
-
-      validateFactoryMethod(getOnlyElement(abstractMethods));
-    }
-
-    /** Validates that the given {@code method} is a valid component factory method. */
-    private void validateFactoryMethod(ExecutableElement method) {
-      validateNotGeneric(method);
-
-      if (!validateFactoryMethodReturnType(method)) {
-        // If we can't determine that the single method is a valid factory method, don't bother
-        // validating its parameters.
-        return;
-      }
-
-      for (VariableElement parameter : method.getParameters()) {
-        if (!isAnnotationPresent(parameter, BindsInstance.class)
-            && parameter.asType().getKind().isPrimitive()) {
-          error(
-              method,
-              messages.nonBindsInstanceParametersMayNotBePrimitives(),
-              messages.inheritedNonBindsInstanceParametersMayNotBePrimitives());
-        }
-      }
-    }
-
-    /**
-     * Validates that the factory method that actually returns a new component instance. Returns
-     * true if the return type was valid.
-     */
-    private boolean validateFactoryMethodReturnType(ExecutableElement method) {
-      TypeMirror returnType = types.resolveExecutableType(method, type.asType()).getReturnType();
-
-      if (!types.isSubtype(component.asType(), returnType)) {
-        error(
-            method,
-            messages.factoryMethodMustReturnComponentType(),
-            messages.inheritedFactoryMethodMustReturnComponentType());
-        return false;
-      }
-
-      if (isAnnotationPresent(method, BindsInstance.class)) {
-        error(
-            method,
-            messages.factoryMethodMayNotBeAnnotatedWithBindsInstance(),
-            messages.inheritedFactoryMethodMayNotBeAnnotatedWithBindsInstance());
-        return false;
-      }
-
-      TypeElement componentType = MoreElements.asType(component);
-      if (!types.isSameType(componentType.asType(), returnType)) {
-        ImmutableSet<ExecutableElement> methodsOnlyInComponent =
-            methodsOnlyInComponent(componentType);
-        if (!methodsOnlyInComponent.isEmpty()) {
-          report.addWarning(
-              messages.factoryMethodReturnsSupertypeWithMissingMethods(
-                  componentType, type, returnType, method, methodsOnlyInComponent),
-              method);
-        }
-      }
-      return true;
-    }
-
-    /**
-     * Generates one of two error messages. If the method is enclosed in the subject, we target the
-     * error to the method itself. Otherwise we target the error to the subject and list the method
-     * as an argument. (Otherwise we have no way of knowing if the method is being compiled in this
-     * pass too, so javac might not be able to pinpoint it's line of code.)
-     */
-    /*
-     * For Component.Builder, the prototypical example would be if someone had:
-     *    libfoo: interface SharedBuilder { void badSetter(A a, B b); }
-     *    libbar: BarComponent { BarBuilder extends SharedBuilder } }
-     * ... the compiler only validates BarBuilder when compiling libbar, but it fails because
-     * of libfoo's SharedBuilder (which could have been compiled in a previous pass).
-     * So we can't point to SharedBuilder#badSetter as the subject of the BarBuilder validation
-     * failure.
-     *
-     * This check is a little more strict than necessary -- ideally we'd check if method's enclosing
-     * class was included in this compile run.  But that's hard, and this is close enough.
-     */
-    private void error(
-        ExecutableElement method,
-        String enclosedError,
-        String inheritedError,
-        Object... extraArgs) {
-      if (method.getEnclosingElement().equals(type)) {
-        report.addError(String.format(enclosedError, extraArgs), method);
-      } else {
-        report.addError(String.format(inheritedError, ObjectArrays.concat(extraArgs, method)));
-      }
-    }
-
-    /** Validates that the given {@code method} is not generic. * */
-    private void validateNotGeneric(ExecutableElement method) {
-      if (!method.getTypeParameters().isEmpty()) {
-        error(
-            method,
-            messages.methodsMayNotHaveTypeParameters(),
-            messages.inheritedMethodsMayNotHaveTypeParameters());
-      }
-    }
-
-    /**
-     * Returns all methods defind in {@code componentType} which are not inherited from a supertype.
-     */
-    private ImmutableSet<ExecutableElement> methodsOnlyInComponent(TypeElement componentType) {
-      // TODO(ronshapiro): Ideally this shouldn't return methods which are redeclared from a
-      // supertype, but do not change the return type. We don't have a good/simple way of checking
-      // that, and it doesn't seem likely, so the warning won't be too bad.
-      return ImmutableSet.copyOf(methodsIn(componentType.getEnclosedElements()));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentDescriptor.java b/java/dagger/internal/codegen/ComponentDescriptor.java
deleted file mode 100644
index 769cc4c..0000000
--- a/java/dagger/internal/codegen/ComponentDescriptor.java
+++ /dev/null
@@ -1,376 +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.DaggerStreams.toImmutableMap;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.langmodel.DaggerTypes.isFutureType;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.type.TypeKind.VOID;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.Component;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.Scope;
-import dagger.producers.CancellationPolicy;
-import dagger.producers.ProductionComponent;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Stream;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A component declaration.
- *
- * <p>Represents one type annotated with {@code @Component}, {@code Subcomponent},
- * {@code @ProductionComponent}, or {@code @ProductionSubcomponent}.
- *
- * <p>When validating bindings installed in modules, a {@link ComponentDescriptor} can also
- * represent a synthetic component for the module, where there is an entry point for each binding in
- * the module.
- */
-@AutoValue
-abstract class ComponentDescriptor {
-  /** The annotation that specifies that {@link #typeElement()} is a component. */
-  abstract ComponentAnnotation annotation();
-
-  /** Returns {@code true} if this is a subcomponent. */
-  final boolean isSubcomponent() {
-    return annotation().isSubcomponent();
-  }
-
-  /**
-   * Returns {@code true} if this is a production component or subcomponent, or a
-   * {@code @ProducerModule} when doing module binding validation.
-   */
-  final boolean isProduction() {
-    return annotation().isProduction();
-  }
-
-  /**
-   * Returns {@code true} if this is a real component, and not a fictional one used to validate
-   * module bindings.
-   */
-  final boolean isRealComponent() {
-    return annotation().isRealComponent();
-  }
-
-  /**
-   * The element that defines the component. This is the element to which the {@link #annotation()}
-   * was applied.
-   */
-  abstract TypeElement typeElement();
-
-  /**
-   * The set of component dependencies listed in {@link Component#dependencies} or {@link
-   * ProductionComponent#dependencies()}.
-   */
-  abstract ImmutableSet<ComponentRequirement> dependencies();
-
-  /** The non-abstract {@link #modules()} and the {@link #dependencies()}. */
-  final ImmutableSet<ComponentRequirement> dependenciesAndConcreteModules() {
-    return Stream.concat(
-            moduleTypes().stream()
-                .filter(dep -> !dep.getModifiers().contains(ABSTRACT))
-                .map(module -> ComponentRequirement.forModule(module.asType())),
-            dependencies().stream())
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * The {@link ModuleDescriptor modules} declared in {@link Component#modules()} and reachable by
-   * traversing {@link Module#includes()}.
-   */
-  abstract ImmutableSet<ModuleDescriptor> modules();
-
-  /** The types of the {@link #modules()}. */
-  final ImmutableSet<TypeElement> moduleTypes() {
-    return modules().stream().map(ModuleDescriptor::moduleElement).collect(toImmutableSet());
-  }
-
-  /**
-   * The types for which the component will need instances if all of its bindings are used. For the
-   * types the component will need in a given binding graph, use {@link
-   * BindingGraph#componentRequirements()}.
-   *
-   * <ul>
-   *   <li>{@linkplain #modules()} modules} with concrete instance bindings
-   *   <li>Bound instances
-   *   <li>{@linkplain #dependencies() dependencies}
-   * </ul>
-   */
-  @Memoized
-  ImmutableSet<ComponentRequirement> requirements() {
-    ImmutableSet.Builder<ComponentRequirement> requirements = ImmutableSet.builder();
-    modules().stream()
-        .filter(
-            module ->
-                module.bindings().stream().anyMatch(ContributionBinding::requiresModuleInstance))
-        .map(module -> ComponentRequirement.forModule(module.moduleElement().asType()))
-        .forEach(requirements::add);
-    requirements.addAll(dependencies());
-    requirements.addAll(
-        creatorDescriptor()
-            .map(ComponentCreatorDescriptor::boundInstanceRequirements)
-            .orElse(ImmutableSet.of()));
-    return requirements.build();
-  }
-
-  /**
-   * This component's {@linkplain #dependencies() dependencies} keyed by each provision or
-   * production method defined by that dependency. Note that the dependencies' types are not simply
-   * the enclosing type of the method; a method may be declared by a supertype of the actual
-   * dependency.
-   */
-  abstract ImmutableMap<ExecutableElement, ComponentRequirement> dependenciesByDependencyMethod();
-
-  /** The {@linkplain #dependencies() component dependency} that defines a method. */
-  final ComponentRequirement getDependencyThatDefinesMethod(Element method) {
-    checkArgument(
-        method instanceof ExecutableElement, "method must be an executable element: %s", method);
-    return checkNotNull(
-        dependenciesByDependencyMethod().get(method), "no dependency implements %s", method);
-  }
-
-  /**
-   * The scopes of the component.
-   */
-  abstract ImmutableSet<Scope> scopes();
-
-  /**
-   * All {@link Subcomponent}s which are direct children of this component. This includes
-   * subcomponents installed from {@link Module#subcomponents()} as well as subcomponent {@linkplain
-   * #childComponentsDeclaredByFactoryMethods() factory methods} and {@linkplain
-   * #childComponentsDeclaredByBuilderEntryPoints() builder methods}.
-   */
-  final ImmutableSet<ComponentDescriptor> childComponents() {
-    return ImmutableSet.<ComponentDescriptor>builder()
-        .addAll(childComponentsDeclaredByFactoryMethods().values())
-        .addAll(childComponentsDeclaredByBuilderEntryPoints().values())
-        .addAll(childComponentsDeclaredByModules())
-        .build();
-  }
-
-  /**
-   * All {@linkplain Subcomponent direct child} components that are declared by a {@linkplain
-   * Module#subcomponents() module's subcomponents}.
-   */
-  abstract ImmutableSet<ComponentDescriptor> childComponentsDeclaredByModules();
-
-  /**
-   * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent
-   * factory method.
-   */
-  abstract ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor>
-      childComponentsDeclaredByFactoryMethods();
-
-  /** Returns a map of {@link #childComponents()} indexed by {@link #typeElement()}. */
-  @Memoized
-  ImmutableMap<TypeElement, ComponentDescriptor> childComponentsByElement() {
-    return Maps.uniqueIndex(childComponents(), ComponentDescriptor::typeElement);
-  }
-
-  /** Returns the factory method that declares a child component. */
-  final Optional<ComponentMethodDescriptor> getFactoryMethodForChildComponent(
-      ComponentDescriptor childComponent) {
-    return Optional.ofNullable(
-        childComponentsDeclaredByFactoryMethods().inverse().get(childComponent));
-  }
-
-  /**
-   * All {@linkplain Subcomponent direct child} components that are declared by a subcomponent
-   * builder method.
-   */
-  abstract ImmutableBiMap<ComponentMethodDescriptor, ComponentDescriptor>
-      childComponentsDeclaredByBuilderEntryPoints();
-
-  private final Supplier<ImmutableMap<TypeElement, ComponentDescriptor>>
-      childComponentsByBuilderType =
-          Suppliers.memoize(
-              () ->
-                  childComponents().stream()
-                      .filter(child -> child.creatorDescriptor().isPresent())
-                      .collect(
-                          toImmutableMap(
-                              child -> child.creatorDescriptor().get().typeElement(),
-                              child -> child)));
-
-  /** Returns the child component with the given builder type. */
-  final ComponentDescriptor getChildComponentWithBuilderType(TypeElement builderType) {
-    return checkNotNull(
-        childComponentsByBuilderType.get().get(builderType),
-        "no child component found for builder type %s",
-        builderType.getQualifiedName());
-  }
-
-  abstract ImmutableSet<ComponentMethodDescriptor> componentMethods();
-
-  /** Returns the first component method associated with this binding request, if one exists. */
-  Optional<ComponentMethodDescriptor> firstMatchingComponentMethod(BindingRequest request) {
-    return componentMethods().stream()
-        .filter(method -> doesComponentMethodMatch(method, request))
-        .findFirst();
-  }
-
-  /** Returns true if the component method matches the binding request. */
-  private static boolean doesComponentMethodMatch(
-      ComponentMethodDescriptor componentMethod, BindingRequest request) {
-    return componentMethod
-        .dependencyRequest()
-        .map(BindingRequest::bindingRequest)
-        .filter(request::equals)
-        .isPresent();
-  }
-
-  /** The entry point methods on the component type. Each has a {@link DependencyRequest}. */
-  final ImmutableSet<ComponentMethodDescriptor> entryPointMethods() {
-    return componentMethods()
-        .stream()
-        .filter(method -> method.dependencyRequest().isPresent())
-        .collect(toImmutableSet());
-  }
-
-  // TODO(gak): Consider making this non-optional and revising the
-  // interaction between the spec & generation
-  /** Returns a descriptor for the creator type for this component type, if the user defined one. */
-  abstract Optional<ComponentCreatorDescriptor> creatorDescriptor();
-
-  /**
-   * Returns {@code true} for components that have a creator, either because the user {@linkplain
-   * #creatorDescriptor() specified one} or because it's a top-level component with an implicit
-   * builder.
-   */
-  final boolean hasCreator() {
-    return !isSubcomponent() || creatorDescriptor().isPresent();
-  }
-
-  /**
-   * Returns the {@link CancellationPolicy} for this component, or an empty optional if either the
-   * component is not a production component or no {@code CancellationPolicy} annotation is present.
-   */
-  final Optional<CancellationPolicy> cancellationPolicy() {
-    return isProduction()
-        ? Optional.ofNullable(typeElement().getAnnotation(CancellationPolicy.class))
-        : Optional.empty();
-  }
-
-  @Memoized
-  @Override
-  public int hashCode() {
-    // TODO(b/122962745): Only use typeElement().hashCode()
-    return Objects.hash(typeElement(), annotation());
-  }
-
-  // TODO(ronshapiro): simplify the equality semantics
-  @Override
-  public abstract boolean equals(Object obj);
-
-  /** A component method. */
-  @AutoValue
-  abstract static class ComponentMethodDescriptor {
-    /** The method itself. Note that this may be declared on a supertype of the component. */
-    abstract ExecutableElement methodElement();
-
-    /**
-     * The dependency request for production, provision, and subcomponent creator methods. Absent
-     * for subcomponent factory methods.
-     */
-    abstract Optional<DependencyRequest> dependencyRequest();
-
-    /** The subcomponent for subcomponent factory methods and subcomponent creator methods. */
-    abstract Optional<ComponentDescriptor> subcomponent();
-
-    /**
-     * Returns the return type of {@link #methodElement()} as resolved in the {@link
-     * ComponentDescriptor#typeElement() component type}. If there are no type variables in the
-     * return type, this is the equivalent of {@code methodElement().getReturnType()}.
-     */
-    TypeMirror resolvedReturnType(DaggerTypes types) {
-      checkState(dependencyRequest().isPresent());
-
-      TypeMirror returnType = methodElement().getReturnType();
-      if (returnType.getKind().isPrimitive() || returnType.getKind().equals(VOID)) {
-        return returnType;
-      }
-      return BindingRequest.bindingRequest(dependencyRequest().get())
-          .requestedType(dependencyRequest().get().key().type(), types);
-    }
-
-    /** A {@link ComponentMethodDescriptor}builder for a method. */
-    static Builder builder(ExecutableElement method) {
-      return new AutoValue_ComponentDescriptor_ComponentMethodDescriptor.Builder()
-          .methodElement(method);
-    }
-
-    /** A builder of {@link ComponentMethodDescriptor}s. */
-    @AutoValue.Builder
-    @CanIgnoreReturnValue
-    interface Builder {
-      /** @see ComponentMethodDescriptor#methodElement() */
-      Builder methodElement(ExecutableElement methodElement);
-
-      /** @see ComponentMethodDescriptor#dependencyRequest() */
-      Builder dependencyRequest(DependencyRequest dependencyRequest);
-
-      /** @see ComponentMethodDescriptor#subcomponent() */
-      Builder subcomponent(ComponentDescriptor subcomponent);
-
-      /** Builds the descriptor. */
-      @CheckReturnValue
-      ComponentMethodDescriptor build();
-    }
-  }
-
-  /** No-argument methods defined on {@link Object} that are ignored for contribution. */
-  private static final ImmutableSet<String> NON_CONTRIBUTING_OBJECT_METHOD_NAMES =
-      ImmutableSet.of("toString", "hashCode", "clone", "getClass");
-
-  /**
-   * Returns {@code true} if a method could be a component entry point but not a members-injection
-   * method.
-   */
-  static boolean isComponentContributionMethod(DaggerElements elements, ExecutableElement method) {
-    return method.getParameters().isEmpty()
-        && !method.getReturnType().getKind().equals(VOID)
-        && !elements.getTypeElement(Object.class).equals(method.getEnclosingElement())
-        && !NON_CONTRIBUTING_OBJECT_METHOD_NAMES.contains(method.getSimpleName().toString());
-  }
-
-  /** Returns {@code true} if a method could be a component production entry point. */
-  static boolean isComponentProductionMethod(DaggerElements elements, ExecutableElement method) {
-    return isComponentContributionMethod(elements, method) && isFutureType(method.getReturnType());
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentDescriptorFactory.java b/java/dagger/internal/codegen/ComponentDescriptorFactory.java
deleted file mode 100644
index 7d87eac..0000000
--- a/java/dagger/internal/codegen/ComponentDescriptorFactory.java
+++ /dev/null
@@ -1,268 +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.auto.common.MoreElements.asType;
-import static com.google.auto.common.MoreTypes.asTypeElement;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentAnnotation.subcomponentAnnotation;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.creatorAnnotationsFor;
-import static dagger.internal.codegen.ComponentDescriptor.isComponentContributionMethod;
-import static dagger.internal.codegen.ConfigurationAnnotations.enclosedAnnotatedTypes;
-import static dagger.internal.codegen.ConfigurationAnnotations.isSubcomponentCreator;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
-import static dagger.internal.codegen.Scopes.productionScope;
-import static dagger.internal.codegen.Scopes.scopesOf;
-import static javax.lang.model.type.TypeKind.DECLARED;
-import static javax.lang.model.type.TypeKind.VOID;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Scope;
-import java.util.Optional;
-import java.util.function.Function;
-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.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/** A factory for {@link ComponentDescriptor}s. */
-final class ComponentDescriptorFactory {
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final DependencyRequestFactory dependencyRequestFactory;
-  private final ModuleDescriptor.Factory moduleDescriptorFactory;
-
-  @Inject
-  ComponentDescriptorFactory(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestFactory dependencyRequestFactory,
-      ModuleDescriptor.Factory moduleDescriptorFactory) {
-    this.elements = elements;
-    this.types = types;
-    this.dependencyRequestFactory = dependencyRequestFactory;
-    this.moduleDescriptorFactory = moduleDescriptorFactory;
-  }
-
-  /** Returns a descriptor for a root component type. */
-  ComponentDescriptor rootComponentDescriptor(TypeElement typeElement) {
-    return create(
-        typeElement,
-        checkAnnotation(
-            typeElement,
-            ComponentAnnotation::rootComponentAnnotation,
-            "must have a component annotation"));
-  }
-
-  /** Returns a descriptor for a subcomponent type. */
-  ComponentDescriptor subcomponentDescriptor(TypeElement typeElement) {
-    return create(
-        typeElement,
-        checkAnnotation(
-            typeElement,
-            ComponentAnnotation::subcomponentAnnotation,
-            "must have a subcomponent annotation"));
-  }
-
-  /**
-   * Returns a descriptor for a fictional component based on a module type in order to validate its
-   * bindings.
-   */
-  ComponentDescriptor moduleComponentDescriptor(TypeElement typeElement) {
-    return create(
-        typeElement,
-        ComponentAnnotation.fromModuleAnnotation(
-            checkAnnotation(
-                typeElement, ModuleAnnotation::moduleAnnotation, "must have a module annotation")));
-  }
-
-  private static <A> A checkAnnotation(
-      TypeElement typeElement,
-      Function<TypeElement, Optional<A>> annotationFunction,
-      String message) {
-    return annotationFunction
-        .apply(typeElement)
-        .orElseThrow(() -> new IllegalArgumentException(typeElement + " " + message));
-  }
-
-  private ComponentDescriptor create(
-      TypeElement typeElement, ComponentAnnotation componentAnnotation) {
-    ImmutableSet<ComponentRequirement> componentDependencies =
-        componentAnnotation.dependencyTypes().stream()
-            .map(ComponentRequirement::forDependency)
-            .collect(toImmutableSet());
-
-    ImmutableMap.Builder<ExecutableElement, ComponentRequirement> dependenciesByDependencyMethod =
-        ImmutableMap.builder();
-
-    for (ComponentRequirement componentDependency : componentDependencies) {
-      for (ExecutableElement dependencyMethod :
-          methodsIn(elements.getAllMembers(componentDependency.typeElement()))) {
-        if (isComponentContributionMethod(elements, dependencyMethod)) {
-          dependenciesByDependencyMethod.put(dependencyMethod, componentDependency);
-        }
-      }
-    }
-
-    // Start with the component's modules. For fictional components built from a module, start with
-    // that module.
-    ImmutableSet<TypeElement> modules =
-        componentAnnotation.isRealComponent()
-            ? componentAnnotation.modules()
-            : ImmutableSet.of(typeElement);
-
-    ImmutableSet<ModuleDescriptor> transitiveModules =
-        moduleDescriptorFactory.transitiveModules(modules);
-
-    ImmutableSet.Builder<ComponentDescriptor> subcomponentsFromModules = ImmutableSet.builder();
-    for (ModuleDescriptor module : transitiveModules) {
-      for (SubcomponentDeclaration subcomponentDeclaration : module.subcomponentDeclarations()) {
-        TypeElement subcomponent = subcomponentDeclaration.subcomponentType();
-        subcomponentsFromModules.add(subcomponentDescriptor(subcomponent));
-      }
-    }
-
-    ImmutableSet.Builder<ComponentMethodDescriptor> componentMethodsBuilder =
-        ImmutableSet.builder();
-    ImmutableBiMap.Builder<ComponentMethodDescriptor, ComponentDescriptor>
-        subcomponentsByFactoryMethod = ImmutableBiMap.builder();
-    ImmutableBiMap.Builder<ComponentMethodDescriptor, ComponentDescriptor>
-        subcomponentsByBuilderMethod = ImmutableBiMap.builder();
-    if (componentAnnotation.isRealComponent()) {
-      ImmutableSet<ExecutableElement> unimplementedMethods =
-          elements.getUnimplementedMethods(typeElement);
-      for (ExecutableElement componentMethod : unimplementedMethods) {
-        ComponentMethodDescriptor componentMethodDescriptor =
-            getDescriptorForComponentMethod(typeElement, componentAnnotation, componentMethod);
-        componentMethodsBuilder.add(componentMethodDescriptor);
-        componentMethodDescriptor
-            .subcomponent()
-            .ifPresent(
-                subcomponent -> {
-                  // If the dependency request is present, that means the method returns the
-                  // subcomponent factory.
-                  if (componentMethodDescriptor.dependencyRequest().isPresent()) {
-                    subcomponentsByBuilderMethod.put(componentMethodDescriptor, subcomponent);
-                  } else {
-                    subcomponentsByFactoryMethod.put(componentMethodDescriptor, subcomponent);
-                  }
-                });
-      }
-    }
-
-    // Validation should have ensured that this set will have at most one element.
-    ImmutableSet<DeclaredType> enclosedCreators =
-        creatorAnnotationsFor(componentAnnotation).stream()
-            .flatMap(
-                creatorAnnotation ->
-                    enclosedAnnotatedTypes(typeElement, creatorAnnotation).stream())
-            .collect(toImmutableSet());
-    Optional<ComponentCreatorDescriptor> creatorDescriptor =
-        enclosedCreators.isEmpty()
-            ? Optional.empty()
-            : Optional.of(
-                ComponentCreatorDescriptor.create(
-                    getOnlyElement(enclosedCreators), elements, types, dependencyRequestFactory));
-
-    ImmutableSet<Scope> scopes = scopesOf(typeElement);
-    if (componentAnnotation.isProduction()) {
-      scopes = ImmutableSet.<Scope>builder().addAll(scopes).add(productionScope(elements)).build();
-    }
-
-    return new AutoValue_ComponentDescriptor(
-        componentAnnotation,
-        typeElement,
-        componentDependencies,
-        transitiveModules,
-        dependenciesByDependencyMethod.build(),
-        scopes,
-        subcomponentsFromModules.build(),
-        subcomponentsByFactoryMethod.build(),
-        subcomponentsByBuilderMethod.build(),
-        componentMethodsBuilder.build(),
-        creatorDescriptor);
-  }
-
-  private ComponentMethodDescriptor getDescriptorForComponentMethod(
-      TypeElement componentElement,
-      ComponentAnnotation componentAnnotation,
-      ExecutableElement componentMethod) {
-    ComponentMethodDescriptor.Builder descriptor =
-        ComponentMethodDescriptor.builder(componentMethod);
-
-    ExecutableType resolvedComponentMethod =
-        MoreTypes.asExecutable(
-            types.asMemberOf(MoreTypes.asDeclared(componentElement.asType()), componentMethod));
-    TypeMirror returnType = resolvedComponentMethod.getReturnType();
-    if (returnType.getKind().equals(DECLARED) && !getQualifier(componentMethod).isPresent()) {
-      TypeElement returnTypeElement = asTypeElement(returnType);
-      if (subcomponentAnnotation(returnTypeElement).isPresent()) {
-        // It's a subcomponent factory method. There is no dependency request, and there could be
-        // any number of parameters. Just return the descriptor.
-        return descriptor.subcomponent(subcomponentDescriptor(returnTypeElement)).build();
-      }
-      if (isSubcomponentCreator(returnTypeElement)) {
-        descriptor.subcomponent(
-            subcomponentDescriptor(asType(returnTypeElement.getEnclosingElement())));
-      }
-    }
-
-    switch (componentMethod.getParameters().size()) {
-      case 0:
-        checkArgument(
-            !returnType.getKind().equals(VOID),
-            "component method cannot be void: %s",
-            componentMethod);
-        descriptor.dependencyRequest(
-            componentAnnotation.isProduction()
-                ? dependencyRequestFactory.forComponentProductionMethod(
-                    componentMethod, resolvedComponentMethod)
-                : dependencyRequestFactory.forComponentProvisionMethod(
-                    componentMethod, resolvedComponentMethod));
-        break;
-
-      case 1:
-        checkArgument(
-            returnType.getKind().equals(VOID)
-                || MoreTypes.equivalence()
-                    .equivalent(returnType, resolvedComponentMethod.getParameterTypes().get(0)),
-            "members injection method must return void or parameter type: %s",
-            componentMethod);
-        descriptor.dependencyRequest(
-            dependencyRequestFactory.forComponentMembersInjectionMethod(
-                componentMethod, resolvedComponentMethod));
-        break;
-
-      default:
-        throw new IllegalArgumentException(
-            "component method has too many parameters: " + componentMethod);
-    }
-
-    return descriptor.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentDescriptorValidator.java b/java/dagger/internal/codegen/ComponentDescriptorValidator.java
deleted file mode 100644
index 8f85b3a..0000000
--- a/java/dagger/internal/codegen/ComponentDescriptorValidator.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2018 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.auto.common.MoreTypes.asDeclared;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Predicates.in;
-import static com.google.common.collect.Collections2.transform;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentAnnotation.rootComponentAnnotation;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSetMultimap;
-import static dagger.internal.codegen.DiagnosticFormatting.stripCommonTypePrefixes;
-import static dagger.internal.codegen.Formatter.INDENT;
-import static dagger.internal.codegen.Scopes.getReadableSource;
-import static dagger.internal.codegen.Scopes.scopesOf;
-import static dagger.internal.codegen.Scopes.singletonScope;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Equivalence.Wrapper;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import dagger.internal.codegen.ComponentRequirement.NullPolicy;
-import dagger.internal.codegen.ErrorMessages.ComponentCreatorMessages;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Scope;
-import java.util.ArrayDeque;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.StringJoiner;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-import javax.tools.Diagnostic;
-
-/**
- * Reports errors in the component hierarchy.
- *
- * <ul>
- *   <li>Validates scope hierarchy of component dependencies and subcomponents.
- *   <li>Reports errors if there are component dependency cycles.
- *   <li>Reports errors if any abstract modules have non-abstract instance binding methods.
- *   <li>Validates component creator types.
- * </ul>
- */
-// TODO(dpb): Combine with ComponentHierarchyValidator.
-final class ComponentDescriptorValidator {
-
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final CompilerOptions compilerOptions;
-  private final MethodSignatureFormatter methodSignatureFormatter;
-  private final ComponentHierarchyValidator componentHierarchyValidator;
-
-  @Inject
-  ComponentDescriptorValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      CompilerOptions compilerOptions,
-      MethodSignatureFormatter methodSignatureFormatter,
-      ComponentHierarchyValidator componentHierarchyValidator) {
-    this.elements = elements;
-    this.types = types;
-    this.compilerOptions = compilerOptions;
-    this.methodSignatureFormatter = methodSignatureFormatter;
-    this.componentHierarchyValidator = componentHierarchyValidator;
-  }
-
-  ValidationReport<TypeElement> validate(ComponentDescriptor component) {
-    ComponentValidation validation = new ComponentValidation(component);
-    validation.visitComponent(component);
-    validation.report(component).addSubreport(componentHierarchyValidator.validate(component));
-    return validation.buildReport();
-  }
-
-  private final class ComponentValidation {
-    final ComponentDescriptor rootComponent;
-    final Map<ComponentDescriptor, ValidationReport.Builder<TypeElement>> reports =
-        new LinkedHashMap<>();
-
-    ComponentValidation(ComponentDescriptor rootComponent) {
-      this.rootComponent = checkNotNull(rootComponent);
-    }
-
-    /** Returns a report that contains all validation messages found during traversal. */
-    ValidationReport<TypeElement> buildReport() {
-      ValidationReport.Builder<TypeElement> report =
-          ValidationReport.about(rootComponent.typeElement());
-      reports.values().forEach(subreport -> report.addSubreport(subreport.build()));
-      return report.build();
-    }
-
-    /** Returns the report builder for a (sub)component. */
-    private ValidationReport.Builder<TypeElement> report(ComponentDescriptor component) {
-      return reentrantComputeIfAbsent(
-          reports, component, descriptor -> ValidationReport.about(descriptor.typeElement()));
-    }
-
-    private void reportComponentItem(
-        Diagnostic.Kind kind, ComponentDescriptor component, String message) {
-      report(component)
-          .addItem(message, kind, component.typeElement(), component.annotation().annotation());
-    }
-
-    private void reportComponentError(ComponentDescriptor component, String error) {
-      reportComponentItem(ERROR, component, error);
-    }
-
-    void visitComponent(ComponentDescriptor component) {
-      validateDependencyScopes(component);
-      validateComponentDependencyHierarchy(component);
-      validateModules(component);
-      validateCreators(component);
-      component.childComponents().forEach(this::visitComponent);
-    }
-
-    /** Validates that component dependencies do not form a cycle. */
-    private void validateComponentDependencyHierarchy(ComponentDescriptor component) {
-      validateComponentDependencyHierarchy(component, component.typeElement(), new ArrayDeque<>());
-    }
-
-    /** Recursive method to validate that component dependencies do not form a cycle. */
-    private void validateComponentDependencyHierarchy(
-        ComponentDescriptor component, TypeElement dependency, Deque<TypeElement> dependencyStack) {
-      if (dependencyStack.contains(dependency)) {
-        // Current component has already appeared in the component chain.
-        StringBuilder message = new StringBuilder();
-        message.append(component.typeElement().getQualifiedName());
-        message.append(" contains a cycle in its component dependencies:\n");
-        dependencyStack.push(dependency);
-        appendIndentedComponentsList(message, dependencyStack);
-        dependencyStack.pop();
-        reportComponentItem(
-            compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
-            component,
-            message.toString());
-      } else {
-        rootComponentAnnotation(dependency)
-            .ifPresent(
-                componentAnnotation -> {
-                  dependencyStack.push(dependency);
-
-                  for (TypeElement nextDependency : componentAnnotation.dependencies()) {
-                    validateComponentDependencyHierarchy(
-                        component, nextDependency, dependencyStack);
-                  }
-
-                  dependencyStack.pop();
-                });
-      }
-    }
-
-    /**
-     * Validates that among the dependencies are at most one scoped dependency, that there are no
-     * cycles within the scoping chain, and that singleton components have no scoped dependencies.
-     */
-    private void validateDependencyScopes(ComponentDescriptor component) {
-      ImmutableSet<Scope> scopes = component.scopes();
-      ImmutableSet<TypeElement> scopedDependencies =
-          scopedTypesIn(
-              component
-                  .dependencies()
-                  .stream()
-                  .map(ComponentRequirement::typeElement)
-                  .collect(toImmutableSet()));
-      if (!scopes.isEmpty()) {
-        Scope singletonScope = singletonScope(elements);
-        // Dagger 1.x scope compatibility requires this be suppress-able.
-        if (compilerOptions.scopeCycleValidationType().diagnosticKind().isPresent()
-            && scopes.contains(singletonScope)) {
-          // Singleton is a special-case representing the longest lifetime, and therefore
-          // @Singleton components may not depend on scoped components
-          if (!scopedDependencies.isEmpty()) {
-            StringBuilder message =
-                new StringBuilder(
-                    "This @Singleton component cannot depend on scoped components:\n");
-            appendIndentedComponentsList(message, scopedDependencies);
-            reportComponentItem(
-                compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
-                component,
-                message.toString());
-          }
-        } else if (scopedDependencies.size() > 1) {
-          // Scoped components may depend on at most one scoped component.
-          StringBuilder message = new StringBuilder();
-          for (Scope scope : scopes) {
-            message.append(getReadableSource(scope)).append(' ');
-          }
-          message
-              .append(component.typeElement().getQualifiedName())
-              .append(" depends on more than one scoped component:\n");
-          appendIndentedComponentsList(message, scopedDependencies);
-          reportComponentError(component, message.toString());
-        } else {
-          // Dagger 1.x scope compatibility requires this be suppress-able.
-          if (!compilerOptions.scopeCycleValidationType().equals(ValidationType.NONE)) {
-            validateDependencyScopeHierarchy(
-                component, component.typeElement(), new ArrayDeque<>(), new ArrayDeque<>());
-          }
-        }
-      } else {
-        // Scopeless components may not depend on scoped components.
-        if (!scopedDependencies.isEmpty()) {
-          StringBuilder message =
-              new StringBuilder(component.typeElement().getQualifiedName())
-                  .append(" (unscoped) cannot depend on scoped components:\n");
-          appendIndentedComponentsList(message, scopedDependencies);
-          reportComponentError(component, message.toString());
-        }
-      }
-    }
-
-    private void validateModules(ComponentDescriptor component) {
-      for (ModuleDescriptor module : component.modules()) {
-        if (module.moduleElement().getModifiers().contains(Modifier.ABSTRACT)) {
-          for (ContributionBinding binding : module.bindings()) {
-            if (binding.requiresModuleInstance()) {
-              report(component).addError(abstractModuleHasInstanceBindingMethodsError(module));
-              break;
-            }
-          }
-        }
-      }
-    }
-
-    private String abstractModuleHasInstanceBindingMethodsError(ModuleDescriptor module) {
-      String methodAnnotations;
-      switch (module.kind()) {
-        case MODULE:
-          methodAnnotations = "@Provides";
-          break;
-        case PRODUCER_MODULE:
-          methodAnnotations = "@Provides or @Produces";
-          break;
-        default:
-          throw new AssertionError(module.kind());
-      }
-      return String.format(
-          "%s is abstract and has instance %s methods. Consider making the methods static or "
-              + "including a non-abstract subclass of the module instead.",
-          module.moduleElement(), methodAnnotations);
-    }
-
-    private void validateCreators(ComponentDescriptor component) {
-      if (!component.creatorDescriptor().isPresent()) {
-        // If no builder, nothing to validate.
-        return;
-      }
-
-      ComponentCreatorDescriptor creator = component.creatorDescriptor().get();
-      ComponentCreatorMessages messages = ErrorMessages.creatorMessagesFor(creator.annotation());
-
-      // Requirements for modules and dependencies that the creator can set
-      Set<ComponentRequirement> creatorModuleAndDependencyRequirements =
-          creator.moduleAndDependencyRequirements();
-      // Modules and dependencies the component requires
-      Set<ComponentRequirement> componentModuleAndDependencyRequirements =
-          component.dependenciesAndConcreteModules();
-
-      // Requirements that the creator can set that don't match any requirements that the component
-      // actually has.
-      Set<ComponentRequirement> inapplicableRequirementsOnCreator =
-          Sets.difference(
-              creatorModuleAndDependencyRequirements, componentModuleAndDependencyRequirements);
-
-      DeclaredType container = asDeclared(creator.typeElement().asType());
-      if (!inapplicableRequirementsOnCreator.isEmpty()) {
-        Collection<Element> excessElements =
-            Multimaps.filterKeys(
-                    creator.unvalidatedRequirementElements(), in(inapplicableRequirementsOnCreator))
-                .values();
-        String formatted =
-            excessElements.stream()
-                .map(element -> formatElement(element, container))
-                .collect(joining(", ", "[", "]"));
-        report(component)
-            .addError(String.format(messages.extraSetters(), formatted), creator.typeElement());
-      }
-
-      // Component requirements that the creator must be able to set
-      Set<ComponentRequirement> mustBePassed =
-          Sets.filter(
-              componentModuleAndDependencyRequirements,
-              input -> input.nullPolicy(elements, types).equals(NullPolicy.THROW));
-      // Component requirements that the creator must be able to set, but can't
-      Set<ComponentRequirement> missingRequirements =
-          Sets.difference(mustBePassed, creatorModuleAndDependencyRequirements);
-
-      if (!missingRequirements.isEmpty()) {
-        report(component)
-            .addError(
-                String.format(
-                    messages.missingSetters(),
-                    missingRequirements.stream().map(ComponentRequirement::type).collect(toList())),
-                creator.typeElement());
-      }
-
-      // Validate that declared creator requirements (modules, dependencies) have unique types.
-      ImmutableSetMultimap<Wrapper<TypeMirror>, Element> declaredRequirementsByType =
-          Multimaps.filterKeys(
-                  creator.unvalidatedRequirementElements(),
-                  creatorModuleAndDependencyRequirements::contains)
-              .entries().stream()
-              .collect(
-                  toImmutableSetMultimap(entry -> entry.getKey().wrappedType(), Entry::getValue));
-      declaredRequirementsByType
-          .asMap()
-          .forEach(
-              (typeWrapper, elementsForType) -> {
-                if (elementsForType.size() > 1) {
-                  TypeMirror type = typeWrapper.get();
-                  // TODO(cgdecker): Attach this error message to the factory method rather than
-                  // the component type if the elements are factory method parameters AND the
-                  // factory method is defined by the factory type itself and not by a supertype.
-                  report(component)
-                      .addError(
-                          String.format(
-                              messages.multipleSettersForModuleOrDependencyType(),
-                              type,
-                              transform(
-                                  elementsForType, element -> formatElement(element, container))),
-                          creator.typeElement());
-                }
-              });
-
-      // TODO(cgdecker): Duplicate binding validation should handle the case of multiple elements
-      // that set the same bound-instance Key, but validating that here would make it fail faster
-      // for subcomponents.
-    }
-
-    private String formatElement(Element element, DeclaredType container) {
-      // TODO(cgdecker): Extract some or all of this to another class?
-      // But note that it does different formatting for parameters than
-      // DaggerElements.elementToString(Element).
-      switch (element.getKind()) {
-        case METHOD:
-          return methodSignatureFormatter.format(
-              MoreElements.asExecutable(element), Optional.of(container));
-        case PARAMETER:
-          return formatParameter(MoreElements.asVariable(element), container);
-        default:
-          // This method shouldn't be called with any other type of element.
-          throw new AssertionError();
-      }
-    }
-
-    private String formatParameter(VariableElement parameter, DeclaredType container) {
-      // TODO(cgdecker): Possibly leave the type (and annotations?) off of the parameters here and
-      // just use their names, since the type will be redundant in the context of the error message.
-      StringJoiner joiner = new StringJoiner(" ");
-      parameter.getAnnotationMirrors().stream().map(Object::toString).forEach(joiner::add);
-      TypeMirror parameterType = resolveParameterType(parameter, container);
-      return joiner
-          .add(stripCommonTypePrefixes(parameterType.toString()))
-          .add(parameter.getSimpleName())
-          .toString();
-    }
-
-    private TypeMirror resolveParameterType(VariableElement parameter, DeclaredType container) {
-      ExecutableElement method =
-          MoreElements.asExecutable(parameter.getEnclosingElement());
-      int parameterIndex = method.getParameters().indexOf(parameter);
-
-      ExecutableType methodType = MoreTypes.asExecutable(types.asMemberOf(container, method));
-      return methodType.getParameterTypes().get(parameterIndex);
-    }
-
-    /**
-     * Validates that scopes do not participate in a scoping cycle - that is to say, scoped
-     * components are in a hierarchical relationship terminating with Singleton.
-     *
-     * <p>As a side-effect, this means scoped components cannot have a dependency cycle between
-     * themselves, since a component's presence within its own dependency path implies a cyclical
-     * relationship between scopes. However, cycles in component dependencies are explicitly checked
-     * in {@link #validateComponentDependencyHierarchy(ComponentDescriptor)}.
-     */
-    private void validateDependencyScopeHierarchy(
-        ComponentDescriptor component,
-        TypeElement dependency,
-        Deque<ImmutableSet<Scope>> scopeStack,
-        Deque<TypeElement> scopedDependencyStack) {
-      ImmutableSet<Scope> scopes = scopesOf(dependency);
-      if (stackOverlaps(scopeStack, scopes)) {
-        scopedDependencyStack.push(dependency);
-        // Current scope has already appeared in the component chain.
-        StringBuilder message = new StringBuilder();
-        message.append(component.typeElement().getQualifiedName());
-        message.append(" depends on scoped components in a non-hierarchical scope ordering:\n");
-        appendIndentedComponentsList(message, scopedDependencyStack);
-        if (compilerOptions.scopeCycleValidationType().diagnosticKind().isPresent()) {
-          reportComponentItem(
-              compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
-              component,
-              message.toString());
-        }
-        scopedDependencyStack.pop();
-      } else {
-        // TODO(beder): transitively check scopes of production components too.
-        rootComponentAnnotation(dependency)
-            .filter(componentAnnotation -> !componentAnnotation.isProduction())
-            .ifPresent(
-                componentAnnotation -> {
-                  ImmutableSet<TypeElement> scopedDependencies =
-                      scopedTypesIn(componentAnnotation.dependencies());
-                  if (scopedDependencies.size() == 1) {
-                    // empty can be ignored (base-case), and > 1 is a separately-reported error.
-                    scopeStack.push(scopes);
-                    scopedDependencyStack.push(dependency);
-                    validateDependencyScopeHierarchy(
-                        component,
-                        getOnlyElement(scopedDependencies),
-                        scopeStack,
-                        scopedDependencyStack);
-                    scopedDependencyStack.pop();
-                    scopeStack.pop();
-                  }
-                }); // else: we skip component dependencies which are not components
-      }
-    }
-
-    private <T> boolean stackOverlaps(Deque<ImmutableSet<T>> stack, ImmutableSet<T> set) {
-      for (ImmutableSet<T> entry : stack) {
-        if (!Sets.intersection(entry, set).isEmpty()) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /** Appends and formats a list of indented component types (with their scope annotations). */
-    private void appendIndentedComponentsList(StringBuilder message, Iterable<TypeElement> types) {
-      for (TypeElement scopedComponent : types) {
-        message.append(INDENT);
-        for (Scope scope : scopesOf(scopedComponent)) {
-          message.append(getReadableSource(scope)).append(' ');
-        }
-        message
-            .append(stripCommonTypePrefixes(scopedComponent.getQualifiedName().toString()))
-            .append('\n');
-      }
-    }
-
-    /**
-     * Returns a set of type elements containing only those found in the input set that have a
-     * scoping annotation.
-     */
-    private ImmutableSet<TypeElement> scopedTypesIn(Collection<TypeElement> types) {
-      return types.stream().filter(type -> !scopesOf(type).isEmpty()).collect(toImmutableSet());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentGenerator.java b/java/dagger/internal/codegen/ComponentGenerator.java
deleted file mode 100644
index 330ec2d..0000000
--- a/java/dagger/internal/codegen/ComponentGenerator.java
+++ /dev/null
@@ -1,71 +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.Verify.verify;
-import static dagger.internal.codegen.SourceFiles.classFileName;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.Component;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Generates the implementation of the abstract types annotated with {@link Component}.
- */
-final class ComponentGenerator extends SourceFileGenerator<BindingGraph> {
-  private final ComponentImplementationFactory componentImplementationFactory;
-
-  @Inject
-  ComponentGenerator(
-      Filer filer,
-      DaggerElements elements,
-      SourceVersion sourceVersion,
-      ComponentImplementationFactory componentImplementationFactory) {
-    super(filer, elements, sourceVersion);
-    this.componentImplementationFactory = componentImplementationFactory;
-  }
-
-  @Override
-  ClassName nameGeneratedType(BindingGraph input) {
-    return componentName(input.componentTypeElement());
-  }
-
-  static ClassName componentName(TypeElement componentDefinitionType) {
-    ClassName componentName = ClassName.get(componentDefinitionType);
-    return ClassName.get(componentName.packageName(), "Dagger" + classFileName(componentName));
-  }
-
-  @Override
-  Element originatingElement(BindingGraph input) {
-    return input.componentTypeElement();
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName componentName, BindingGraph bindingGraph) {
-    ComponentImplementation componentImplementation =
-        componentImplementationFactory.createComponentImplementation(bindingGraph);
-    verify(componentImplementation.name().equals(componentName));
-    return Optional.of(componentImplementation.generate());
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentHierarchyValidator.java b/java/dagger/internal/codegen/ComponentHierarchyValidator.java
deleted file mode 100644
index d1e5333..0000000
--- a/java/dagger/internal/codegen/ComponentHierarchyValidator.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2015 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.Functions.constant;
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.in;
-import static com.google.common.base.Predicates.not;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.Scopes.getReadableSource;
-import static dagger.internal.codegen.Scopes.uniqueScopeOf;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.model.Scope;
-import java.util.Collection;
-import java.util.Formatter;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-
-/** Validates the relationships between parent components and subcomponents. */
-final class ComponentHierarchyValidator {
-  private static final Joiner COMMA_SEPARATED_JOINER = Joiner.on(", ");
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  ComponentHierarchyValidator(CompilerOptions compilerOptions) {
-    this.compilerOptions = compilerOptions;
-  }
-
-  ValidationReport<TypeElement> validate(ComponentDescriptor componentDescriptor) {
-    ValidationReport.Builder<TypeElement> report =
-        ValidationReport.about(componentDescriptor.typeElement());
-    validateSubcomponentMethods(
-        report,
-        componentDescriptor,
-        Maps.toMap(componentDescriptor.moduleTypes(), constant(componentDescriptor.typeElement())));
-    validateRepeatedScopedDeclarations(report, componentDescriptor, LinkedHashMultimap.create());
-
-    if (compilerOptions.scopeCycleValidationType().diagnosticKind().isPresent()) {
-      validateScopeHierarchy(
-          report, componentDescriptor, LinkedHashMultimap.<ComponentDescriptor, Scope>create());
-    }
-    validateProductionModuleUniqueness(report, componentDescriptor, LinkedHashMultimap.create());
-    return report.build();
-  }
-
-  private void validateSubcomponentMethods(
-      ValidationReport.Builder<?> report,
-      ComponentDescriptor componentDescriptor,
-      ImmutableMap<TypeElement, TypeElement> existingModuleToOwners) {
-    componentDescriptor
-        .childComponentsDeclaredByFactoryMethods()
-        .forEach(
-            (method, childComponent) -> {
-              if (childComponent.hasCreator()) {
-                report.addError(
-                    "Components may not have factory methods for subcomponents that define a "
-                        + "builder.",
-                    method.methodElement());
-              } else {
-                validateFactoryMethodParameters(report, method, existingModuleToOwners);
-              }
-
-              validateSubcomponentMethods(
-                  report,
-                  childComponent,
-                  new ImmutableMap.Builder<TypeElement, TypeElement>()
-                      .putAll(existingModuleToOwners)
-                      .putAll(
-                          Maps.toMap(
-                              Sets.difference(
-                                  childComponent.moduleTypes(), existingModuleToOwners.keySet()),
-                              constant(childComponent.typeElement())))
-                      .build());
-            });
-  }
-
-  private void validateFactoryMethodParameters(
-      ValidationReport.Builder<?> report,
-      ComponentMethodDescriptor subcomponentMethodDescriptor,
-      ImmutableMap<TypeElement, TypeElement> existingModuleToOwners) {
-    for (VariableElement factoryMethodParameter :
-        subcomponentMethodDescriptor.methodElement().getParameters()) {
-      TypeElement moduleType = MoreTypes.asTypeElement(factoryMethodParameter.asType());
-      TypeElement originatingComponent = existingModuleToOwners.get(moduleType);
-      if (originatingComponent != null) {
-        /* Factory method tries to pass a module that is already present in the parent.
-         * This is an error. */
-        report.addError(
-            String.format(
-                "%s is present in %s. A subcomponent cannot use an instance of a "
-                    + "module that differs from its parent.",
-                moduleType.getSimpleName(), originatingComponent.getQualifiedName()),
-            factoryMethodParameter);
-      }
-    }
-  }
-
-  /**
-   * Checks that components do not have any scopes that are also applied on any of their ancestors.
-   */
-  private void validateScopeHierarchy(
-      ValidationReport.Builder<TypeElement> report,
-      ComponentDescriptor subject,
-      SetMultimap<ComponentDescriptor, Scope> scopesByComponent) {
-    scopesByComponent.putAll(subject, subject.scopes());
-
-    for (ComponentDescriptor childComponent : subject.childComponents()) {
-      validateScopeHierarchy(report, childComponent, scopesByComponent);
-    }
-
-    scopesByComponent.removeAll(subject);
-
-    Predicate<Scope> subjectScopes =
-        subject.isProduction()
-            // TODO(beder): validate that @ProductionScope is only applied on production components
-            ? and(in(subject.scopes()), not(Scope::isProductionScope))
-            : in(subject.scopes());
-    SetMultimap<ComponentDescriptor, Scope> overlappingScopes =
-        Multimaps.filterValues(scopesByComponent, subjectScopes);
-    if (!overlappingScopes.isEmpty()) {
-      StringBuilder error =
-          new StringBuilder()
-              .append(subject.typeElement().getQualifiedName())
-              .append(" has conflicting scopes:");
-      for (Map.Entry<ComponentDescriptor, Scope> entry : overlappingScopes.entries()) {
-        Scope scope = entry.getValue();
-        error
-            .append("\n  ")
-            .append(entry.getKey().typeElement().getQualifiedName())
-            .append(" also has ")
-            .append(getReadableSource(scope));
-      }
-      report.addItem(
-          error.toString(),
-          compilerOptions.scopeCycleValidationType().diagnosticKind().get(),
-          subject.typeElement());
-    }
-  }
-
-  private void validateProductionModuleUniqueness(
-      ValidationReport.Builder<TypeElement> report,
-      ComponentDescriptor componentDescriptor,
-      SetMultimap<ComponentDescriptor, ModuleDescriptor> producerModulesByComponent) {
-    ImmutableSet<ModuleDescriptor> producerModules =
-        componentDescriptor.modules().stream()
-            .filter(module -> module.kind().equals(ModuleKind.PRODUCER_MODULE))
-            .collect(toImmutableSet());
-
-    producerModulesByComponent.putAll(componentDescriptor, producerModules);
-    for (ComponentDescriptor childComponent : componentDescriptor.childComponents()) {
-      validateProductionModuleUniqueness(report, childComponent, producerModulesByComponent);
-    }
-    producerModulesByComponent.removeAll(componentDescriptor);
-
-    SetMultimap<ComponentDescriptor, ModuleDescriptor> repeatedModules =
-        Multimaps.filterValues(producerModulesByComponent, producerModules::contains);
-    if (repeatedModules.isEmpty()) {
-      return;
-    }
-
-    StringBuilder error = new StringBuilder();
-    Formatter formatter = new Formatter(error);
-
-    formatter.format("%s repeats @ProducerModules:", componentDescriptor.typeElement());
-
-    for (Map.Entry<ComponentDescriptor, Collection<ModuleDescriptor>> entry :
-        repeatedModules.asMap().entrySet()) {
-      formatter.format("\n  %s also installs: ", entry.getKey().typeElement());
-      COMMA_SEPARATED_JOINER
-          .appendTo(error, Iterables.transform(entry.getValue(), m -> m.moduleElement()));
-    }
-
-    report.addError(error.toString());
-  }
-
-  private void validateRepeatedScopedDeclarations(
-      ValidationReport.Builder<TypeElement> report,
-      ComponentDescriptor component,
-      // TODO(ronshapiro): optimize ModuleDescriptor.hashCode()/equals. Otherwise this could be
-      // quite costly
-      SetMultimap<ComponentDescriptor, ModuleDescriptor> modulesWithScopes) {
-    ImmutableSet<ModuleDescriptor> modules =
-        component.modules().stream().filter(this::hasScopedDeclarations).collect(toImmutableSet());
-    modulesWithScopes.putAll(component, modules);
-    for (ComponentDescriptor childComponent : component.childComponents()) {
-      validateRepeatedScopedDeclarations(report, childComponent, modulesWithScopes);
-    }
-    modulesWithScopes.removeAll(component);
-
-    SetMultimap<ComponentDescriptor, ModuleDescriptor> repeatedModules =
-        Multimaps.filterValues(modulesWithScopes, modules::contains);
-    if (repeatedModules.isEmpty()) {
-      return;
-    }
-
-    report.addError(
-        repeatedModulesWithScopeError(component, ImmutableSetMultimap.copyOf(repeatedModules)));
-  }
-
-  private boolean hasScopedDeclarations(ModuleDescriptor module) {
-    return !moduleScopes(module).isEmpty();
-  }
-
-  private String repeatedModulesWithScopeError(
-      ComponentDescriptor component,
-      ImmutableSetMultimap<ComponentDescriptor, ModuleDescriptor> repeatedModules) {
-    StringBuilder error =
-        new StringBuilder()
-            .append(component.typeElement().getQualifiedName())
-            .append(" repeats modules with scoped bindings or declarations:");
-
-    repeatedModules
-        .asMap()
-        .forEach(
-            (conflictingComponent, conflictingModules) -> {
-              error
-                  .append("\n  - ")
-                  .append(conflictingComponent.typeElement().getQualifiedName())
-                  .append(" also includes:");
-              for (ModuleDescriptor conflictingModule : conflictingModules) {
-                error
-                    .append("\n    - ")
-                    .append(conflictingModule.moduleElement().getQualifiedName())
-                    .append(" with scopes: ")
-                    .append(COMMA_SEPARATED_JOINER.join(moduleScopes(conflictingModule)));
-              }
-            });
-    return error.toString();
-  }
-
-  private ImmutableSet<Scope> moduleScopes(ModuleDescriptor module) {
-    return FluentIterable.concat(module.allBindingDeclarations())
-        .transform(declaration -> uniqueScopeOf(declaration.bindingElement().get()))
-        .filter(scope -> scope.isPresent() && !scope.get().isReusable())
-        .transform(scope -> scope.get())
-        .toSet();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentHjarProcessingStep.java b/java/dagger/internal/codegen/ComponentHjarProcessingStep.java
deleted file mode 100644
index 47857ca..0000000
--- a/java/dagger/internal/codegen/ComponentHjarProcessingStep.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2017 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.squareup.javapoet.MethodSpec.constructorBuilder;
-import static dagger.internal.codegen.ComponentAnnotation.rootComponentAnnotations;
-import static dagger.internal.codegen.ComponentCreatorKind.BUILDER;
-import static dagger.internal.codegen.ComponentGenerator.componentName;
-import static dagger.internal.codegen.javapoet.TypeSpecs.addSupertype;
-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;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Ascii;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.BindsInstance;
-import dagger.internal.codegen.ComponentValidator.ComponentValidationReport;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.producers.internal.CancellationListener;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-
-/**
- * A processing step that emits the API of a generated component, without any actual implementation.
- *
- * <p>When compiling a header jar (hjar), Bazel needs to run annotation processors that generate
- * API, like Dagger, to see what code they might output. Full {@link BindingGraph} analysis is
- * costly and unnecessary from the perspective of the header compiler; it's sole goal is to pass
- * along a slimmed down version of what will be the jar for a particular compilation, whether or not
- * that compilation succeeds. If it does not, the compilation pipeline will fail, even if header
- * compilation succeeded.
- *
- * <p>The components emitted by this processing step include all of the API elements exposed by the
- * normal step. Method bodies are omitted as Turbine ignores them entirely.
- */
-final class ComponentHjarProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
-  private final SourceVersion sourceVersion;
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final Filer filer;
-  private final Messager messager;
-  private final ComponentValidator componentValidator;
-  private final ComponentDescriptorFactory componentDescriptorFactory;
-
-  @Inject
-  ComponentHjarProcessingStep(
-      SourceVersion sourceVersion,
-      DaggerElements elements,
-      DaggerTypes types,
-      Filer filer,
-      Messager messager,
-      ComponentValidator componentValidator,
-      ComponentDescriptorFactory componentDescriptorFactory) {
-    super(MoreElements::asType);
-    this.sourceVersion = sourceVersion;
-    this.elements = elements;
-    this.types = types;
-    this.filer = filer;
-    this.messager = messager;
-    this.componentValidator = componentValidator;
-    this.componentDescriptorFactory = componentDescriptorFactory;
-  }
-
-  @Override
-  public Set<Class<? extends Annotation>> annotations() {
-    return rootComponentAnnotations();
-  }
-
-  @Override
-  protected void process(
-      TypeElement componentTypeElement, ImmutableSet<Class<? extends Annotation>> annotations) {
-    // TODO(ronshapiro): component validation might not be necessary. We should measure it and
-    // figure out if it's worth seeing if removing it will still work. We could potentially add a
-    // new catch clause for any exception that's not TypeNotPresentException and ignore the
-    // component entirely in that case.
-    ComponentValidationReport validationReport =
-        componentValidator.validate(componentTypeElement, ImmutableSet.of(), ImmutableSet.of());
-    validationReport.report().printMessagesTo(messager);
-    if (validationReport.report().isClean()) {
-      new EmptyComponentGenerator(filer, elements, sourceVersion)
-          .generate(
-              componentDescriptorFactory.rootComponentDescriptor(componentTypeElement), messager);
-    }
-  }
-
-  private final class EmptyComponentGenerator extends SourceFileGenerator<ComponentDescriptor> {
-    EmptyComponentGenerator(Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-      super(filer, elements, sourceVersion);
-    }
-
-    @Override
-    ClassName nameGeneratedType(ComponentDescriptor input) {
-      return componentName(input.typeElement());
-    }
-
-    @Override
-    Element originatingElement(ComponentDescriptor input) {
-      return input.typeElement();
-    }
-
-    @Override
-    Optional<TypeSpec.Builder> write(
-        ClassName generatedTypeName, ComponentDescriptor componentDescriptor) {
-      TypeSpec.Builder generatedComponent =
-          TypeSpec.classBuilder(generatedTypeName)
-              .addModifiers(FINAL)
-              .addMethod(privateConstructor());
-      if (componentDescriptor.typeElement().getModifiers().contains(PUBLIC)) {
-        generatedComponent.addModifiers(PUBLIC);
-      }
-
-      TypeElement componentElement = componentDescriptor.typeElement();
-      addSupertype(generatedComponent, componentElement);
-
-      TypeName builderMethodReturnType;
-      ComponentCreatorKind creatorKind;
-      boolean noArgFactoryMethod;
-      if (componentDescriptor.creatorDescriptor().isPresent()) {
-        ComponentCreatorDescriptor creatorDescriptor =
-            componentDescriptor.creatorDescriptor().get();
-        builderMethodReturnType = ClassName.get(creatorDescriptor.typeElement());
-        creatorKind = creatorDescriptor.kind();
-        noArgFactoryMethod = creatorDescriptor.factoryParameters().isEmpty();
-      } else {
-        TypeSpec.Builder builder =
-            TypeSpec.classBuilder("Builder")
-                .addModifiers(STATIC, FINAL)
-                .addMethod(privateConstructor());
-        if (componentDescriptor.typeElement().getModifiers().contains(PUBLIC)) {
-          builder.addModifiers(PUBLIC);
-        }
-
-        ClassName builderClassName = generatedTypeName.nestedClass("Builder");
-        builderMethodReturnType = builderClassName;
-        creatorKind = BUILDER;
-        noArgFactoryMethod = true;
-        componentRequirements(componentDescriptor)
-            .map(requirement -> builderSetterMethod(requirement.typeElement(), builderClassName))
-            .forEach(builder::addMethod);
-        builder.addMethod(builderBuildMethod(componentDescriptor));
-        generatedComponent.addType(builder.build());
-      }
-
-      generatedComponent.addMethod(staticCreatorMethod(builderMethodReturnType, creatorKind));
-
-      if (noArgFactoryMethod
-          && !hasBindsInstanceMethods(componentDescriptor)
-          && componentRequirements(componentDescriptor)
-              .noneMatch(requirement -> requirement.requiresAPassedInstance(elements, types))) {
-        generatedComponent.addMethod(createMethod(componentDescriptor));
-      }
-
-      DeclaredType componentType = MoreTypes.asDeclared(componentElement.asType());
-      // TODO(ronshapiro): unify with ComponentImplementationBuilder
-      Set<MethodSignature> methodSignatures =
-          Sets.newHashSetWithExpectedSize(componentDescriptor.componentMethods().size());
-      componentDescriptor
-          .componentMethods()
-          .stream()
-          .filter(
-              method -> {
-                return methodSignatures.add(
-                    MethodSignature.forComponentMethod(method, componentType, types));
-              })
-          .forEach(
-              method ->
-                  generatedComponent.addMethod(
-                      emptyComponentMethod(componentElement, method.methodElement())));
-
-      if (componentDescriptor.isProduction()) {
-        generatedComponent
-            .addSuperinterface(ClassName.get(CancellationListener.class))
-            .addMethod(onProducerFutureCancelledMethod());
-      }
-
-      return Optional.of(generatedComponent);
-    }
-  }
-
-  private MethodSpec emptyComponentMethod(TypeElement typeElement, ExecutableElement baseMethod) {
-    return MethodSpec.overriding(baseMethod, MoreTypes.asDeclared(typeElement.asType()), types)
-        .build();
-  }
-
-  private MethodSpec privateConstructor() {
-    return constructorBuilder().addModifiers(PRIVATE).build();
-  }
-
-  /**
-   * Returns the {@link ComponentRequirement}s for a component that does not have a {@link
-   * ComponentDescriptor#creatorDescriptor()}.
-   */
-  private Stream<ComponentRequirement> componentRequirements(ComponentDescriptor component) {
-    checkArgument(!component.isSubcomponent());
-    return Stream.concat(
-        component.dependencies().stream(),
-        component.modules().stream()
-            .filter(module -> !module.moduleElement().getModifiers().contains(ABSTRACT))
-            .map(module -> ComponentRequirement.forModule(module.moduleElement().asType())));
-  }
-
-  private boolean hasBindsInstanceMethods(ComponentDescriptor componentDescriptor) {
-    return componentDescriptor.creatorDescriptor().isPresent()
-        && elements
-            .getUnimplementedMethods(componentDescriptor.creatorDescriptor().get().typeElement())
-            .stream()
-            .anyMatch(method -> isBindsInstance(method));
-  }
-
-  private static boolean isBindsInstance(ExecutableElement method) {
-    if (isAnnotationPresent(method, BindsInstance.class)) {
-      return true;
-    }
-
-    if (method.getParameters().size() == 1) {
-      return isAnnotationPresent(method.getParameters().get(0), BindsInstance.class);
-    }
-
-    return false;
-  }
-
-  private MethodSpec builderSetterMethod(
-      TypeElement componentRequirement, ClassName builderClass) {
-    String simpleName =
-        UPPER_CAMEL.to(LOWER_CAMEL, componentRequirement.getSimpleName().toString());
-    return MethodSpec.methodBuilder(simpleName)
-        .addModifiers(PUBLIC)
-        .addParameter(ClassName.get(componentRequirement), simpleName)
-        .returns(builderClass)
-        .build();
-  }
-
-  private MethodSpec builderBuildMethod(ComponentDescriptor component) {
-    return MethodSpec.methodBuilder("build")
-        .addModifiers(PUBLIC)
-        .returns(ClassName.get(component.typeElement()))
-        .build();
-  }
-
-  private MethodSpec staticCreatorMethod(
-      TypeName creatorMethodReturnType, ComponentCreatorKind creatorKind) {
-    return MethodSpec.methodBuilder(Ascii.toLowerCase(creatorKind.typeName()))
-        .addModifiers(PUBLIC, STATIC)
-        .returns(creatorMethodReturnType)
-        .build();
-  }
-
-  private MethodSpec createMethod(ComponentDescriptor componentDescriptor) {
-    return MethodSpec.methodBuilder("create")
-        .addModifiers(PUBLIC, STATIC)
-        .returns(ClassName.get(componentDescriptor.typeElement()))
-        .build();
-  }
-
-  private MethodSpec onProducerFutureCancelledMethod() {
-    return MethodSpec.methodBuilder("onProducerFutureCancelled")
-        .addModifiers(PUBLIC)
-        .addParameter(TypeName.BOOLEAN, "mayInterruptIfRunning")
-        .build();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentImplementation.java b/java/dagger/internal/codegen/ComponentImplementation.java
deleted file mode 100644
index 340da14..0000000
--- a/java/dagger/internal/codegen/ComponentImplementation.java
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * Copyright (C) 2016 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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-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 com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.ComponentCreatorKind.BUILDER;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static dagger.internal.codegen.serialization.ProtoSerialization.toAnnotationValue;
-import static java.util.stream.Collectors.toList;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PUBLIC;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.MultimapBuilder;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.ConfigureInitializationParameters;
-import dagger.internal.ModifiableBinding;
-import dagger.internal.ModifiableModule;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.TypeSpecs;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/** The implementation of a component type. */
-final class ComponentImplementation {
-  /** A type of field that this component can contain. */
-  enum FieldSpecKind {
-
-    /** A field required by the component, e.g. module instances. */
-    COMPONENT_REQUIREMENT_FIELD,
-
-    /**
-     * A field for the lock and cached value for {@linkplain PrivateMethodBindingExpression
-     * private-method scoped bindings}.
-     */
-    PRIVATE_METHOD_SCOPED_FIELD,
-
-    /** A framework field for type T, e.g. {@code Provider<T>}. */
-    FRAMEWORK_FIELD,
-
-    /** A static field that always returns an absent {@code Optional} value for the binding. */
-    ABSENT_OPTIONAL_FIELD
-  }
-
-  /** A type of method that this component can contain. */
-  // TODO(user, dpb): Change the oder to constructor, initialize, component, then private
-  // (including MIM and AOM—why treat those separately?).
-  enum MethodSpecKind {
-    /** The component constructor. */
-    CONSTRUCTOR,
-
-    /**
-     * In ahead-of-time subcomponents, this method coordinates the invocation of {@link
-     * #INITIALIZE_METHOD initialization methods} instead of constructors.
-     */
-    // TODO(b/117833324): try to merge this with other initialize() methods so it looks more natural
-    CONFIGURE_INITIALIZATION_METHOD,
-
-    /** A builder method for the component. (Only used by the root component.) */
-    BUILDER_METHOD,
-
-    /** A private method that wraps dependency expressions. */
-    PRIVATE_METHOD,
-
-    /** An initialization method that initializes component requirements and framework types. */
-    INITIALIZE_METHOD,
-
-    /** An implementation of a component interface method. */
-    COMPONENT_METHOD,
-
-    /** A private method that encapsulates members injection logic for a binding. */
-    MEMBERS_INJECTION_METHOD,
-
-    /** A static method that always returns an absent {@code Optional} value for the binding. */
-    ABSENT_OPTIONAL_METHOD,
-
-    /**
-     * A method that encapsulates a modifiable binding. A binding is modifiable if it can change
-     * across implementations of a subcomponent. This is only relevant for ahead-of-time
-     * subcomponents.
-     */
-    MODIFIABLE_BINDING_METHOD,
-
-    /**
-     * The {@link dagger.producers.internal.CancellationListener#onProducerFutureCancelled(boolean)}
-     * method for a production component.
-     */
-    CANCELLATION_LISTENER_METHOD,
-    ;
-  }
-
-  /** A type of nested class that this component can contain. */
-  enum TypeSpecKind {
-    /** A factory class for a present optional binding. */
-    PRESENT_FACTORY,
-
-    /** A class for the component creator (only used by the root component.) */
-    COMPONENT_CREATOR,
-
-    /** A provider class for a component provision. */
-    COMPONENT_PROVISION_FACTORY,
-
-    /** A class for the subcomponent or subcomponent builder. */
-    SUBCOMPONENT
-  }
-
-  /**
-   * The method spec for a {@code configureInitialization} method plus details on the component
-   * requirements that its parameters are associated with.
-   */
-  @AutoValue
-  abstract static class ConfigureInitializationMethod {
-    /** Creates a new {@link ConfigureInitializationMethod}. */
-    static ConfigureInitializationMethod create(
-        MethodSpec spec, ImmutableSet<ComponentRequirement> parameters) {
-      return new AutoValue_ComponentImplementation_ConfigureInitializationMethod(spec, parameters);
-    }
-
-    /** The spec for the method. */
-    abstract MethodSpec spec();
-
-    /**
-     * The component requirements associated with the method's parameters, in the same order as the
-     * parameters.
-     */
-    abstract ImmutableSet<ComponentRequirement> parameters();
-  }
-
-  private final CompilerOptions compilerOptions;
-  private final ComponentDescriptor componentDescriptor;
-  private final Optional<BindingGraph> graph;
-  private final ClassName name;
-  private final NestingKind nestingKind;
-  private final boolean isAbstract;
-  private final Optional<ComponentImplementation> superclassImplementation;
-  private Optional<ComponentCreatorImplementation> creatorImplementation;
-  private final Map<TypeElement, ComponentImplementation> childImplementations = new HashMap<>();
-  private final TypeSpec.Builder component;
-  private final Optional<SubcomponentNames> subcomponentNames;
-  private final UniqueNameSet componentFieldNames = new UniqueNameSet();
-  private final UniqueNameSet componentMethodNames = new UniqueNameSet();
-  private final List<CodeBlock> initializations = new ArrayList<>();
-  private final Set<ComponentRequirement> componentRequirementParameters = new HashSet<>();
-  private final List<CodeBlock> componentRequirementInitializations = new ArrayList<>();
-  private final Map<ComponentRequirement, String> componentRequirementParameterNames =
-      new HashMap<>();
-  private final Set<Key> cancellableProducerKeys = new LinkedHashSet<>();
-  private final ListMultimap<FieldSpecKind, FieldSpec> fieldSpecsMap =
-      MultimapBuilder.enumKeys(FieldSpecKind.class).arrayListValues().build();
-  private final ListMultimap<MethodSpecKind, MethodSpec> methodSpecsMap =
-      MultimapBuilder.enumKeys(MethodSpecKind.class).arrayListValues().build();
-  private final ListMultimap<TypeSpecKind, TypeSpec> typeSpecsMap =
-      MultimapBuilder.enumKeys(TypeSpecKind.class).arrayListValues().build();
-  private final List<Supplier<TypeSpec>> switchingProviderSupplier = new ArrayList<>();
-  private final ModifiableBindingMethods modifiableBindingMethods = new ModifiableBindingMethods();
-  private final SetMultimap<BindingRequest, Key> multibindingContributionsMade =
-      LinkedHashMultimap.create();
-  private Optional<ConfigureInitializationMethod> configureInitializationMethod = Optional.empty();
-  private final Map<ComponentRequirement, String> modifiableModuleMethods = new LinkedHashMap<>();
-
-  private ComponentImplementation(
-      ComponentDescriptor componentDescriptor,
-      Optional<BindingGraph> graph,
-      ClassName name,
-      NestingKind nestingKind,
-      Optional<ComponentImplementation> superclassImplementation,
-      Optional<SubcomponentNames> subcomponentNames,
-      CompilerOptions compilerOptions,
-      ImmutableSet<Modifier> modifiers) {
-    checkName(name, nestingKind);
-    this.compilerOptions = compilerOptions;
-    this.componentDescriptor = componentDescriptor;
-    this.graph = graph;
-    this.name = name;
-    this.nestingKind = nestingKind;
-    this.isAbstract = modifiers.contains(ABSTRACT);
-    this.superclassImplementation = superclassImplementation;
-    this.component = classBuilder(name);
-    modifiers.forEach(component::addModifiers);
-    this.subcomponentNames = subcomponentNames;
-  }
-
-  /** Returns a component implementation for a top-level component. */
-  static ComponentImplementation topLevelComponentImplementation(
-      BindingGraph graph,
-      ClassName name,
-      SubcomponentNames subcomponentNames,
-      CompilerOptions compilerOptions) {
-    return new ComponentImplementation(
-        graph.componentDescriptor(),
-        Optional.of(graph),
-        name,
-        NestingKind.TOP_LEVEL,
-        Optional.empty(), // superclass implementation
-        Optional.of(subcomponentNames),
-        compilerOptions,
-        topLevelComponentImplementationModifiers(graph));
-  }
-
-  private static ImmutableSet<Modifier> topLevelComponentImplementationModifiers(
-      BindingGraph graph) {
-    ImmutableSet.Builder<Modifier> modifiers = ImmutableSet.builder();
-    if (graph.componentTypeElement().getModifiers().contains(PUBLIC)
-        || graph.componentDescriptor().isSubcomponent()) {
-      // TODO(ronshapiro): perhaps all generated components should be non-public?
-      modifiers.add(PUBLIC);
-    }
-    return modifiers.add(graph.componentDescriptor().isSubcomponent() ? ABSTRACT : FINAL).build();
-  }
-
-  /** Returns a component implementation that is a child of the current implementation. */
-  ComponentImplementation childComponentImplementation(
-      BindingGraph graph,
-      Optional<ComponentImplementation> superclassImplementation,
-      Modifier... modifiers) {
-    return new ComponentImplementation(
-        graph.componentDescriptor(),
-        Optional.of(graph),
-        getSubcomponentName(graph.componentDescriptor()),
-        NestingKind.MEMBER,
-        superclassImplementation,
-        subcomponentNames,
-        compilerOptions,
-        ImmutableSet.copyOf(modifiers));
-  }
-
-  /**
-   * Returns a component implementation that models a previously compiled class. This {@link
-   * ComponentImplementation} is not used for code generation itself; it is used to determine what
-   * methods need to be implemented in a subclass implementation.
-   */
-  static ComponentImplementation forDeserializedComponent(
-      ComponentDescriptor componentDescriptor,
-      ClassName name,
-      NestingKind nestingKind,
-      Optional<ComponentImplementation> superclassImplementation,
-      CompilerOptions compilerOptions) {
-    return new ComponentImplementation(
-        componentDescriptor,
-        Optional.empty(),
-        name,
-        nestingKind,
-        superclassImplementation,
-        Optional.empty(),
-        compilerOptions,
-        ImmutableSet.of(PUBLIC, ABSTRACT));
-  }
-
-  // TODO(dpb): Just determine the nesting kind from the name.
-  private static void checkName(ClassName name, NestingKind nestingKind) {
-    switch (nestingKind) {
-      case TOP_LEVEL:
-        checkArgument(
-            name.enclosingClassName() == null, "must be a top-level class name: %s", name);
-        break;
-
-      case MEMBER:
-        checkNotNull(name.enclosingClassName(), "must not be a top-level class name: %s", name);
-        break;
-
-      default:
-        throw new IllegalArgumentException(
-            "nestingKind must be TOP_LEVEL or MEMBER: " + nestingKind);
-    }
-  }
-
-  /**
-   * Returns {@code true} if this component implementation represents a component that has already
-   * been compiled. If this returns true, the implementation will have no {@link #graph
-   * BindingGraph}.
-   */
-  boolean isDeserializedImplementation() {
-    return !graph.isPresent();
-  }
-
-  // TODO(ronshapiro): see if we can remove this method and instead inject it in the objects that
-  // need it.
-  /** Returns the binding graph for the component being generated. */
-  BindingGraph graph() {
-    checkState(!isDeserializedImplementation(),
-        "A BindingGraph is not available for deserialized component implementations.");
-    return graph.get();
-  }
-
-  /** Returns the descriptor for the component being generated. */
-  ComponentDescriptor componentDescriptor() {
-    return componentDescriptor;
-  }
-
-  /** Returns the name of the component. */
-  ClassName name() {
-    return name;
-  }
-
-  /** Returns whether or not the implementation is nested within another class. */
-  boolean isNested() {
-    return nestingKind.isNested();
-  }
-
-  /** Returns whether or not the implementation is abstract. */
-  boolean isAbstract() {
-    return isAbstract;
-  }
-
-  /** Returns the superclass implementation. */
-  Optional<ComponentImplementation> superclassImplementation() {
-    return superclassImplementation;
-  }
-
-  /**
-   * Returns the base implementation of this component in ahead-of-time subcomponents mode. If this
-   * is the base implementation, this returns {@link Optional#empty()}.
-   */
-  Optional<ComponentImplementation> baseImplementation() {
-    return superclassImplementation.isPresent()
-        ? Optional.of(Optionals.rootmostValue(this, c -> c.superclassImplementation))
-        : Optional.empty();
-  }
-
-  /**
-   * Returns the {@link #configureInitializationMethod()} of the nearest supertype that defines one,
-   * if any.
-   *
-   * <p>Only returns a present value in {@link CompilerOptions#aheadOfTimeSubcomponents()}.
-   */
-  Optional<ConfigureInitializationMethod> superConfigureInitializationMethod() {
-    for (Optional<ComponentImplementation> currentSuper = superclassImplementation;
-        currentSuper.isPresent();
-        currentSuper = currentSuper.get().superclassImplementation) {
-      if (currentSuper.get().configureInitializationMethod.isPresent()) {
-        return currentSuper.get().configureInitializationMethod;
-      }
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * The requirements for creating an instance of this component implementation type.
-   *
-   * <p>If this component implementation is concrete, these requirements will be in the order that
-   * the implementation's constructor takes them as parameters.
-   */
-  ImmutableSet<ComponentRequirement> requirements() {
-    // If the base implementation's creator is being generated in ahead-of-time-subcomponents
-    // mode, this uses the ComponentDescriptor's requirements() since Dagger doesn't know what
-    // modules may end being unused or owned by an ancestor component. Otherwise, we use the
-    // necessary component requirements.
-    // TODO(ronshapiro): can we remove the second condition here? Or, is it never going to be
-    // called, so we should enforce that invariant?
-    return isAbstract() && !superclassImplementation().isPresent()
-        ? componentDescriptor().requirements()
-        : graph().componentRequirements();
-  }
-
-  /**
-   * Returns the {@link MethodSpecKind#CONFIGURE_INITIALIZATION_METHOD} of this implementation if
-   * there is one.
-   *
-   * <p>Only returns a present value in {@link CompilerOptions#aheadOfTimeSubcomponents()}.
-   */
-  Optional<ConfigureInitializationMethod> configureInitializationMethod() {
-    return configureInitializationMethod;
-  }
-
-  /**
-   * Set's this component implementation's {@code configureInitialization()} method and {@linkplain
-   * #addMethod(MethodSpecKind, MethodSpec) adds the method}.
-   */
-  void setConfigureInitializationMethod(ConfigureInitializationMethod method) {
-    configureInitializationMethod = Optional.of(method);
-    addMethod(
-        MethodSpecKind.CONFIGURE_INITIALIZATION_METHOD,
-        addConfigureInitializationMetadata(method));
-  }
-
-  private MethodSpec addConfigureInitializationMetadata(ConfigureInitializationMethod method) {
-    if (!shouldEmitModifiableMetadataAnnotations()) {
-      return method.spec();
-    }
-    AnnotationSpec.Builder annotation =
-        AnnotationSpec.builder(ConfigureInitializationParameters.class);
-    for (ComponentRequirement parameter : method.parameters()) {
-      annotation.addMember("value", toAnnotationValue(parameter.toProto()));
-    }
-
-    return method.spec().toBuilder().addAnnotation(annotation.build()).build();
-  }
-
-  void setCreatorImplementation(Optional<ComponentCreatorImplementation> creatorImplementation) {
-    checkState(
-        this.creatorImplementation == null, "setCreatorImplementation has already been called");
-    this.creatorImplementation = creatorImplementation;
-  }
-
-  Optional<ComponentCreatorImplementation> creatorImplementation() {
-    checkState(creatorImplementation != null, "setCreatorImplementation has not been called yet");
-    return creatorImplementation;
-  }
-
-  /**
-   * Returns the {@link ComponentCreatorImplementation} defined in the base implementation for this
-   * component, if one exists.
-   */
-  Optional<ComponentCreatorImplementation> baseCreatorImplementation() {
-    return baseImplementation().flatMap(baseImpl -> baseImpl.creatorImplementation());
-  }
-
-  /**
-   * Returns the kind of this component's creator.
-   *
-   * @throws IllegalStateException if the component has no creator
-   */
-  private ComponentCreatorKind creatorKind() {
-    checkState(componentDescriptor().hasCreator());
-    return componentDescriptor()
-        .creatorDescriptor()
-        .map(ComponentCreatorDescriptor::kind)
-        .orElse(BUILDER);
-  }
-
-  /**
-   * Returns the name of the creator class for this component. It will be a sibling of this
-   * generated class unless this is a top-level component, in which case it will be nested.
-   */
-  ClassName getCreatorName() {
-    return isNested()
-        ? name.peerClass(subcomponentNames().getCreatorName(componentDescriptor()))
-        : name.nestedClass(creatorKind().typeName());
-  }
-
-  /** Returns the name of the nested implementation class for a child component. */
-  ClassName getSubcomponentName(ComponentDescriptor childDescriptor) {
-    checkArgument(
-        componentDescriptor().childComponents().contains(childDescriptor),
-        "%s is not a child component of %s",
-        childDescriptor.typeElement(),
-        componentDescriptor().typeElement());
-    return name.nestedClass(subcomponentNames().get(childDescriptor) + "Impl");
-  }
-
-  /**
-   * Returns the simple name of the creator implementation class for the given subcomponent creator
-   * {@link Key}.
-   */
-  String getSubcomponentCreatorSimpleName(Key key) {
-    return subcomponentNames().getCreatorName(key);
-  }
-
-  private SubcomponentNames subcomponentNames() {
-    checkState(
-        subcomponentNames.isPresent(),
-        "SubcomponentNames is not available for deserialized component implementations.");
-    return subcomponentNames.get();
-  }
-
-  /** Returns the child implementation. */
-  Optional<ComponentImplementation> childImplementation(ComponentDescriptor child) {
-    return Optional.ofNullable(childImplementations.get(child.typeElement()));
-  }
-
-  /** Returns {@code true} if {@code type} is accessible from the generated component. */
-  boolean isTypeAccessible(TypeMirror type) {
-    return isTypeAccessibleFrom(type, name.packageName());
-  }
-
-  /** Adds the given super type to the component. */
-  void addSupertype(TypeElement supertype) {
-    TypeSpecs.addSupertype(component, supertype);
-  }
-
-  /** Adds the given super class to the subcomponent. */
-  void addSuperclass(ClassName className) {
-    checkState(
-        superclassImplementation.isPresent(),
-        "Setting the superclass for component [%s] when there is no superclass implementation.",
-        name);
-    component.superclass(className);
-  }
-
-  // TODO(dpb): Consider taking FieldSpec, and returning identical FieldSpec with unique name?
-  /** Adds the given field to the component. */
-  void addField(FieldSpecKind fieldKind, FieldSpec fieldSpec) {
-    fieldSpecsMap.put(fieldKind, fieldSpec);
-  }
-
-  /** Adds the given fields to the component. */
-  void addFields(FieldSpecKind fieldKind, Iterable<FieldSpec> fieldSpecs) {
-    fieldSpecsMap.putAll(fieldKind, fieldSpecs);
-  }
-
-  // TODO(dpb): Consider taking MethodSpec, and returning identical MethodSpec with unique name?
-  /** Adds the given method to the component. */
-  void addMethod(MethodSpecKind methodKind, MethodSpec methodSpec) {
-    methodSpecsMap.put(methodKind, methodSpec);
-  }
-
-  /** Adds the given annotation to the component. */
-  void addAnnotation(AnnotationSpec annotation) {
-    component.addAnnotation(annotation);
-  }
-
-  /**
-   * Adds the given method to the component. In this case, the method represents an encapsulation of
-   * a modifiable binding between implementations of a subcomponent. This is only relevant for
-   * ahead-of-time subcomponents.
-   */
-  void addModifiableBindingMethod(
-      ModifiableBindingType type,
-      BindingRequest request,
-      TypeMirror returnType,
-      MethodSpec methodSpec,
-      boolean finalized) {
-    addModifiableMethod(
-        MethodSpecKind.MODIFIABLE_BINDING_METHOD, type, request, returnType, methodSpec, finalized);
-  }
-
-  /**
-   * Adds a component method that is modifiable to the component. In this case, the method
-   * represents an encapsulation of a modifiable binding between implementations of a subcomponent.
-   * This is only relevant for ahead-of-time subcomponents.
-   */
-  void addModifiableComponentMethod(
-      ModifiableBindingType type,
-      BindingRequest request,
-      TypeMirror returnType,
-      MethodSpec methodSpec,
-      boolean finalized) {
-    addModifiableMethod(
-        MethodSpecKind.COMPONENT_METHOD, type, request, returnType, methodSpec, finalized);
-  }
-
-  private void addModifiableMethod(
-      MethodSpecKind methodKind,
-      ModifiableBindingType type,
-      BindingRequest request,
-      TypeMirror returnType,
-      MethodSpec methodSpec,
-      boolean finalized) {
-    modifiableBindingMethods.addModifiableMethod(
-        type, request, returnType, methodSpec, finalized);
-    methodSpecsMap.put(methodKind, withModifiableBindingMetadata(methodSpec, type, request));
-  }
-
-  /** Adds the implementation for the given {@link ModifiableBindingMethod} to the component. */
-  void addImplementedModifiableBindingMethod(ModifiableBindingMethod method) {
-    modifiableBindingMethods.addReimplementedMethod(method);
-    methodSpecsMap.put(
-        MethodSpecKind.MODIFIABLE_BINDING_METHOD,
-        withModifiableBindingMetadata(method.methodSpec(), method.type(), method.request()));
-  }
-
-  private MethodSpec withModifiableBindingMetadata(
-      MethodSpec method, ModifiableBindingType type, BindingRequest request) {
-    if (!shouldEmitModifiableMetadataAnnotations()) {
-      return method;
-    }
-    AnnotationSpec.Builder metadata =
-        AnnotationSpec.builder(ModifiableBinding.class)
-            .addMember("modifiableBindingType", "$S", type.name())
-            .addMember("bindingRequest", toAnnotationValue(request.toProto()));
-    for (Key multibindingContribution : multibindingContributionsMade.get(request)) {
-      metadata.addMember(
-          "multibindingContributions",
-          toAnnotationValue(KeyFactory.toProto(multibindingContribution)));
-    }
-    return method.toBuilder().addAnnotation(metadata.build()).build();
-  }
-
-  /** Add's a modifiable module method to this implementation. */
-  void addModifiableModuleMethod(ComponentRequirement module, MethodSpec method) {
-    registerModifiableModuleMethod(module, method.name);
-    methodSpecsMap.put(
-        MethodSpecKind.MODIFIABLE_BINDING_METHOD, withModifiableModuleMetadata(module, method));
-  }
-
-  /** Registers a modifiable module method with {@code name} for {@code module}. */
-  void registerModifiableModuleMethod(ComponentRequirement module, String name) {
-    checkArgument(module.kind().isModule());
-    checkState(modifiableModuleMethods.put(module, name) == null);
-  }
-
-  private MethodSpec withModifiableModuleMetadata(ComponentRequirement module, MethodSpec method) {
-    if (!shouldEmitModifiableMetadataAnnotations()) {
-      return method;
-    }
-    return method
-        .toBuilder()
-        .addAnnotation(
-            AnnotationSpec.builder(ModifiableModule.class)
-                .addMember("value", toAnnotationValue(module.toProto()))
-                .build())
-        .build();
-  }
-
-  /**
-   * Returns {@code true} if the generated component should include metadata annotations with
-   * information to deserialize this {@link ComponentImplementation} in future compilations.
-   */
-  boolean shouldEmitModifiableMetadataAnnotations() {
-    return isAbstract && compilerOptions.emitModifiableMetadataAnnotations();
-  }
-
-  /** Adds the given type to the component. */
-  void addType(TypeSpecKind typeKind, TypeSpec typeSpec) {
-    typeSpecsMap.put(typeKind, typeSpec);
-  }
-
-  /** Adds the type generated from the given child implementation. */
-  void addChild(ComponentDescriptor child, ComponentImplementation childImplementation) {
-    childImplementations.put(child.typeElement(), childImplementation);
-    addType(TypeSpecKind.SUBCOMPONENT, childImplementation.generate().build());
-  }
-
-  /** Adds a {@link Supplier} for the SwitchingProvider for the component. */
-  void addSwitchingProvider(Supplier<TypeSpec> typeSpecSupplier) {
-    switchingProviderSupplier.add(typeSpecSupplier);
-  }
-
-  /** Adds the given code block to the initialize methods of the component. */
-  void addInitialization(CodeBlock codeBlock) {
-    initializations.add(codeBlock);
-  }
-
-  /**
-   * Adds the given component requirement as one that should have a parameter in the component's
-   * initialization methods.
-   */
-  void addComponentRequirementParameter(ComponentRequirement requirement) {
-    componentRequirementParameters.add(requirement);
-  }
-
-  /**
-   * The set of component requirements that have parameters in the component's initialization
-   * methods.
-   */
-  ImmutableSet<ComponentRequirement> getComponentRequirementParameters() {
-    return ImmutableSet.copyOf(componentRequirementParameters);
-  }
-
-  /** Adds the given code block that initializes a {@link ComponentRequirement}. */
-  void addComponentRequirementInitialization(CodeBlock codeBlock) {
-    componentRequirementInitializations.add(codeBlock);
-  }
-
-  /**
-   * Marks the given key of a producer as one that should have a cancellation statement in the
-   * cancellation listener method of the component.
-   */
-  void addCancellableProducerKey(Key key) {
-    cancellableProducerKeys.add(key);
-  }
-
-  /** Returns a new, unique field name for the component based on the given name. */
-  String getUniqueFieldName(String name) {
-    return componentFieldNames.getUniqueName(name);
-  }
-
-  /** Returns a new, unique method name for the component based on the given name. */
-  String getUniqueMethodName(String name) {
-    return componentMethodNames.getUniqueName(name);
-  }
-
-  /** Returns a new, unique method name for a getter method for the given request. */
-  String getUniqueMethodName(BindingRequest request) {
-    return uniqueMethodName(request, KeyVariableNamer.name(request.key()));
-  }
-
-  private String uniqueMethodName(BindingRequest request, String bindingName) {
-    String baseMethodName =
-        "get"
-            + LOWER_CAMEL.to(UPPER_CAMEL, bindingName)
-            + (request.isRequestKind(RequestKind.INSTANCE)
-                ? ""
-                : UPPER_UNDERSCORE.to(UPPER_CAMEL, request.kindName()));
-    return getUniqueMethodName(baseMethodName);
-  }
-
-  /** Gets the parameter name to use for the given requirement for this component. */
-  String getParameterName(ComponentRequirement requirement) {
-    return getParameterName(requirement, requirement.variableName());
-  }
-
-  /**
-   * Gets the parameter name to use for the given requirement for this component, starting with the
-   * given base name if no parameter name has already been selected for the requirement.
-   */
-  String getParameterName(ComponentRequirement requirement, String baseName) {
-    return componentRequirementParameterNames.computeIfAbsent(
-        requirement, r -> getUniqueFieldName(baseName));
-  }
-
-  /** Claims a new method name for the component. Does nothing if method name already exists. */
-  void claimMethodName(CharSequence name) {
-    componentMethodNames.claim(name);
-  }
-
-  /** Returns the list of {@link CodeBlock}s that need to go in the initialize method. */
-  ImmutableList<CodeBlock> getInitializations() {
-    return ImmutableList.copyOf(initializations);
-  }
-
-  /**
-   * Returns a list of {@link CodeBlock}s for initializing {@link ComponentRequirement}s.
-   *
-   * <p>These initializations are kept separate from {@link #getInitializations()} because they must
-   * be executed before the initializations of any framework instance initializations in a
-   * superclass implementation that may depend on the instances. We cannot use the same strategy
-   * that we use for framework instances (i.e. wrap in a {@link dagger.internal.DelegateFactory} or
-   * {@link dagger.producers.internal.DelegateProducer} since the types of these initialized fields
-   * have no interface type that we can write a proxy for.
-   */
-  ImmutableList<CodeBlock> getComponentRequirementInitializations() {
-    return ImmutableList.copyOf(componentRequirementInitializations);
-  }
-
-  /**
-   * Returns whether or not this component has any {@linkplain #getInitializations() initilizations}
-   * or {@linkplain #getComponentRequirementInitializations() component requirement
-   * initializations}.
-   */
-  boolean hasInitializations() {
-    return !initializations.isEmpty() || !componentRequirementInitializations.isEmpty();
-  }
-
-  /**
-   * Returns the list of producer {@link Key}s that need cancellation statements in the cancellation
-   * listener method.
-   */
-  ImmutableList<Key> getCancellableProducerKeys() {
-    Optional<ComponentImplementation> currentSuperImplementation = superclassImplementation;
-    Set<Key> cancelledKeysFromSuperclass = new HashSet<>();
-    while (currentSuperImplementation.isPresent()) {
-      cancelledKeysFromSuperclass.addAll(currentSuperImplementation.get().cancellableProducerKeys);
-      currentSuperImplementation = currentSuperImplementation.get().superclassImplementation;
-    }
-    return Sets.difference(cancellableProducerKeys, cancelledKeysFromSuperclass)
-        .immutableCopy()
-        .asList();
-  }
-
-  /**
-   * Returns the {@link ModifiableBindingMethod}s for this subcomponent implementation and its
-   * superclasses.
-   */
-  ImmutableMap<BindingRequest, ModifiableBindingMethod> getModifiableBindingMethods() {
-    Map<BindingRequest, ModifiableBindingMethod> modifiableBindingMethodsBuilder =
-        new LinkedHashMap<>();
-    if (superclassImplementation.isPresent()) {
-      modifiableBindingMethodsBuilder.putAll(
-          Maps.filterValues(
-              superclassImplementation.get().getModifiableBindingMethods(),
-              // filters the modifiable methods of a superclass that are finalized in this component
-              method -> !modifiableBindingMethods.finalized(method)));
-    }
-    // replace superclass modifiable binding methods with any that are defined in this component
-    // implementation
-    modifiableBindingMethodsBuilder.putAll(modifiableBindingMethods.getNonFinalizedMethods());
-    return ImmutableMap.copyOf(modifiableBindingMethodsBuilder);
-  }
-
-  /**
-   * Returns the names of every modifiable method of this implementation and any superclass
-   * implementations.
-   */
-  ImmutableSet<String> getAllModifiableMethodNames() {
-    ImmutableSet.Builder<String> names = ImmutableSet.builder();
-    modifiableBindingMethods.allMethods().forEach(method -> names.add(method.methodSpec().name));
-    names.addAll(modifiableModuleMethods.values());
-    superclassImplementation.ifPresent(
-        superclass -> names.addAll(superclass.getAllModifiableMethodNames()));
-    return names.build();
-  }
-
-  /**
-   * Returns the {@link ModifiableBindingMethod} for this subcomponent for the given binding, if it
-   * exists.
-   */
-  Optional<ModifiableBindingMethod> getModifiableBindingMethod(BindingRequest request) {
-    Optional<ModifiableBindingMethod> method = modifiableBindingMethods.getMethod(request);
-    if (!method.isPresent() && superclassImplementation.isPresent()) {
-      return superclassImplementation.get().getModifiableBindingMethod(request);
-    }
-    return method;
-  }
-
-  /**
-   * Returns the {@link ModifiableBindingMethod} of a supertype for this method's {@code request},
-   * if one exists.
-   */
-  Optional<ModifiableBindingMethod> supertypeModifiableBindingMethod(BindingRequest request) {
-    return superclassImplementation()
-        .flatMap(superImplementation -> superImplementation.getModifiableBindingMethod(request));
-  }
-
-  /**
-   * Returns the names of modifiable module methods for this implementation and all inherited
-   * implementations, keyed by the corresponding module's {@link ComponentRequirement}.
-   */
-  ImmutableMap<ComponentRequirement, String> getAllModifiableModuleMethods() {
-    ImmutableMap.Builder<ComponentRequirement, String> methods = ImmutableMap.builder();
-    methods.putAll(modifiableModuleMethods);
-    superclassImplementation.ifPresent(
-        superclass -> methods.putAll(superclass.getAllModifiableModuleMethods()));
-    return methods.build();
-  }
-
-  /**
-   * Returns the name of the modifiable module method for {@code module} that is inherited in this
-   * implementation, or empty if none has been defined.
-   */
-  Optional<String> supertypeModifiableModuleMethodName(ComponentRequirement module) {
-    checkArgument(module.kind().isModule());
-    if (!superclassImplementation.isPresent()) {
-      return Optional.empty();
-    }
-    String methodName = superclassImplementation.get().modifiableModuleMethods.get(module);
-    if (methodName == null) {
-      return superclassImplementation.get().supertypeModifiableModuleMethodName(module);
-    }
-    return Optional.of(methodName);
-  }
-
-  /** Generates the component and returns the resulting {@link TypeSpec.Builder}. */
-  TypeSpec.Builder generate() {
-    fieldSpecsMap.asMap().values().forEach(component::addFields);
-    methodSpecsMap.asMap().values().forEach(component::addMethods);
-    typeSpecsMap.asMap().values().forEach(component::addTypes);
-    switchingProviderSupplier.stream().map(Supplier::get).forEach(component::addType);
-    return component;
-  }
-
-  /**
-   * Registers a {@ProvisionBinding} representing a multibinding as having been implemented in this
-   * component. Multibindings are modifiable across subcomponent implementations and this allows us
-   * to know whether a contribution has been made by a superclass implementation. This is only
-   * relevant for ahead-of-time subcomponents.
-   */
-  void registerImplementedMultibinding(
-      ContributionBinding multibinding, BindingRequest bindingRequest) {
-    checkArgument(multibinding.isSyntheticMultibinding());
-    // We register a multibinding as implemented each time we request the multibinding expression,
-    // so only modify the set of contributions once.
-    if (!multibindingContributionsMade.containsKey(bindingRequest)) {
-      registerImplementedMultibindingKeys(
-          bindingRequest,
-          multibinding.dependencies().stream().map(DependencyRequest::key).collect(toList()));
-    }
-  }
-
-  /**
-   * Registers the multibinding contributions represented by {@code keys} as having been implemented
-   * in this component. Multibindings are modifiable across subcomponent implementations and this
-   * allows us to know whether a contribution has been made by a superclass implementation. This is
-   * only relevant for ahead-of-time subcomponents.
-   */
-  void registerImplementedMultibindingKeys(BindingRequest bindingRequest, Iterable<Key> keys) {
-    multibindingContributionsMade.putAll(bindingRequest, keys);
-  }
-
-  /**
-   * Returns the set of multibinding contributions associated with all superclass implementations of
-   * a multibinding.
-   */
-  ImmutableSet<Key> superclassContributionsMade(BindingRequest bindingRequest) {
-    return superclassImplementation
-        .map(s -> s.getAllMultibindingContributions(bindingRequest))
-        .orElse(ImmutableSet.of());
-  }
-
-  /**
-   * Returns the set of multibinding contributions associated with all implementations of a
-   * multibinding.
-   */
-  private ImmutableSet<Key> getAllMultibindingContributions(BindingRequest bindingRequest) {
-    return ImmutableSet.copyOf(
-        Sets.union(
-            multibindingContributionsMade.get(bindingRequest),
-            superclassContributionsMade(bindingRequest)));
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentImplementationBuilder.java b/java/dagger/internal/codegen/ComponentImplementationBuilder.java
deleted file mode 100644
index 7579ac9..0000000
--- a/java/dagger/internal/codegen/ComponentImplementationBuilder.java
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreElements.getLocalAndInheritedMethods;
-import static com.google.auto.common.MoreTypes.asDeclared;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Predicates.in;
-import static com.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.ComponentCreatorKind.BUILDER;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.BUILDER_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.CANCELLATION_LISTENER_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.COMPONENT_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.CONSTRUCTOR;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.INITIALIZE_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.MODIFIABLE_BINDING_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.TypeSpecKind.COMPONENT_CREATOR;
-import static dagger.internal.codegen.ComponentImplementation.TypeSpecKind.SUBCOMPONENT;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.CodeBlocks.parameterNames;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.producers.CancellationPolicy.Propagation.PROPAGATE;
-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.PROTECTED;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.ComponentDefinitionType;
-import dagger.internal.Preconditions;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ComponentImplementation.ConfigureInitializationMethod;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.AnnotationSpecs;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import dagger.producers.internal.CancellationListener;
-import dagger.producers.internal.Producers;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-
-/** A builder of {@link ComponentImplementation}s. */
-abstract class ComponentImplementationBuilder {
-  private static final String MAY_INTERRUPT_IF_RUNNING = "mayInterruptIfRunning";
-
-  /**
-   * How many statements per {@code initialize()} or {@code onProducerFutureCancelled()} method
-   * before they get partitioned.
-   */
-  private static final int STATEMENTS_PER_METHOD = 100;
-
-  private static final String CANCELLATION_LISTENER_METHOD_NAME = "onProducerFutureCancelled";
-
-  // TODO(ronshapiro): replace this with composition instead of inheritance so we don't have
-  // non-final fields
-  @Inject BindingGraph graph;
-  @Inject ComponentBindingExpressions bindingExpressions;
-  @Inject ComponentRequirementExpressions componentRequirementExpressions;
-  @Inject ComponentImplementation componentImplementation;
-  @Inject ComponentCreatorImplementationFactory componentCreatorImplementationFactory;
-  @Inject DaggerTypes types;
-  @Inject DaggerElements elements;
-  @Inject CompilerOptions compilerOptions;
-  @Inject ComponentImplementationFactory componentImplementationFactory;
-  @Inject TopLevelImplementationComponent topLevelImplementationComponent;
-  private boolean done;
-
-  /**
-   * Returns a {@link ComponentImplementation} for this component. This is only intended to be
-   * called once (and will throw on successive invocations). If the component must be regenerated,
-   * use a new instance.
-   */
-  final ComponentImplementation build() {
-    checkState(
-        !done,
-        "ComponentImplementationBuilder has already built the ComponentImplementation for [%s].",
-        componentImplementation.name());
-    setSupertype();
-    componentImplementation.setCreatorImplementation(
-        componentCreatorImplementationFactory.create(
-            componentImplementation, Optional.of(componentImplementation.graph())));
-    componentImplementation
-        .creatorImplementation()
-        .map(ComponentCreatorImplementation::spec)
-        .ifPresent(this::addCreatorClass);
-
-    getLocalAndInheritedMethods(graph.componentTypeElement(), types, elements)
-        .forEach(method -> componentImplementation.claimMethodName(method.getSimpleName()));
-    componentImplementation
-        .superclassImplementation()
-        .ifPresent(
-            superclassImplementation -> {
-              superclassImplementation
-                  .getAllModifiableMethodNames()
-                  .forEach(componentImplementation::claimMethodName);
-            });
-
-    addFactoryMethods();
-    addInterfaceMethods();
-    addChildComponents();
-    implementModifiableModuleMethods();
-
-    addConstructorAndInitializationMethods();
-
-    if (graph.componentDescriptor().isProduction()) {
-      addCancellationListenerImplementation();
-    }
-
-    if (componentImplementation.isAbstract()
-        && !componentImplementation.baseImplementation().isPresent()) {
-      componentImplementation.addAnnotation(compilerOptions.toGenerationOptionsAnnotation());
-    }
-
-    if (componentImplementation.shouldEmitModifiableMetadataAnnotations()) {
-      componentImplementation.addAnnotation(
-          AnnotationSpec.builder(ComponentDefinitionType.class)
-              .addMember("value", "$T.class", graph.componentTypeElement())
-              .build());
-    }
-
-    done = true;
-    return componentImplementation;
-  }
-
-  /** Set the supertype for this generated class. */
-  private void setSupertype() {
-    if (componentImplementation.superclassImplementation().isPresent()) {
-      componentImplementation.addSuperclass(
-          componentImplementation.superclassImplementation().get().name());
-    } else {
-      componentImplementation.addSupertype(graph.componentTypeElement());
-    }
-  }
-
-  /**
-   * Adds {@code creator} as a nested creator class. Root components and subcomponents will nest
-   * this in different classes.
-   */
-  protected abstract void addCreatorClass(TypeSpec creator);
-
-  /** Adds component factory methods. */
-  protected abstract void addFactoryMethods();
-
-  protected void addInterfaceMethods() {
-    // Each component method may have been declared by several supertypes. We want to implement
-    // only one method for each distinct signature.
-    ImmutableListMultimap<MethodSignature, ComponentMethodDescriptor> componentMethodsBySignature =
-        Multimaps.index(graph.componentDescriptor().entryPointMethods(), this::getMethodSignature);
-    for (List<ComponentMethodDescriptor> methodsWithSameSignature :
-        Multimaps.asMap(componentMethodsBySignature).values()) {
-      ComponentMethodDescriptor anyOneMethod = methodsWithSameSignature.stream().findAny().get();
-      MethodSpec methodSpec = bindingExpressions.getComponentMethod(anyOneMethod);
-
-      if (compilerOptions.aheadOfTimeSubcomponents()) {
-        addPossiblyModifiableInterfaceMethod(anyOneMethod, methodSpec);
-      } else {
-        componentImplementation.addMethod(COMPONENT_METHOD, methodSpec);
-      }
-    }
-  }
-
-  /**
-   * Adds a component interface method in ahead-of-time subcomponents mode. If the binding that
-   * implements the method is modifiable, registers the method.
-   */
-  private void addPossiblyModifiableInterfaceMethod(
-      ComponentMethodDescriptor methodDescriptor, MethodSpec implementedComponentMethod) {
-    if (methodDescriptor.dependencyRequest().isPresent()
-        && componentImplementation
-            .getModifiableBindingMethod(bindingRequest(methodDescriptor.dependencyRequest().get()))
-            .isPresent()) {
-      // If there are multiple component methods that are modifiable and for the same binding
-      // request, implement all but one in the base implementation to delegate to the one that
-      // will remain (and be registered) modifiable
-      checkState(componentImplementation.isAbstract() && !componentImplementation.isNested());
-      componentImplementation.addMethod(
-          COMPONENT_METHOD, implementedComponentMethod.toBuilder().addModifiers(FINAL).build());
-    } else {
-      // TODO(b/117833324): Can this class be the one to interface with ComponentImplementation
-      // instead of having it go through ModifiableBindingExpressions?
-      bindingExpressions
-          .modifiableBindingExpressions()
-          .addPossiblyModifiableComponentMethod(methodDescriptor, implementedComponentMethod);
-    }
-  }
-
-  private void addCancellationListenerImplementation() {
-    componentImplementation.addSupertype(elements.getTypeElement(CancellationListener.class));
-    componentImplementation.claimMethodName(CANCELLATION_LISTENER_METHOD_NAME);
-
-    ImmutableList<ParameterSpec> parameters =
-        ImmutableList.of(ParameterSpec.builder(boolean.class, MAY_INTERRUPT_IF_RUNNING).build());
-
-    MethodSpec.Builder methodBuilder =
-        methodBuilder(CANCELLATION_LISTENER_METHOD_NAME)
-            .addModifiers(PUBLIC)
-            .addAnnotation(Override.class)
-            .addParameters(parameters);
-    if (componentImplementation.superclassImplementation().isPresent()) {
-      methodBuilder.addStatement(
-          "super.$L($L)", CANCELLATION_LISTENER_METHOD_NAME, MAY_INTERRUPT_IF_RUNNING);
-    }
-
-    ImmutableList<CodeBlock> cancellationStatements = cancellationStatements();
-
-    if (cancellationStatements.size() < STATEMENTS_PER_METHOD) {
-      methodBuilder.addCode(CodeBlocks.concat(cancellationStatements)).build();
-    } else {
-      ImmutableList<MethodSpec> cancelProducersMethods =
-          createPartitionedMethods(
-              "cancelProducers",
-              parameters,
-              cancellationStatements,
-              methodName -> methodBuilder(methodName).addModifiers(PRIVATE));
-      for (MethodSpec cancelProducersMethod : cancelProducersMethods) {
-        methodBuilder.addStatement("$N($L)", cancelProducersMethod, MAY_INTERRUPT_IF_RUNNING);
-        componentImplementation.addMethod(CANCELLATION_LISTENER_METHOD, cancelProducersMethod);
-      }
-    }
-
-    Optional<CodeBlock> cancelParentStatement = cancelParentStatement();
-    cancelParentStatement.ifPresent(methodBuilder::addCode);
-
-    if (cancellationStatements.isEmpty()
-        && !cancelParentStatement.isPresent()
-        && componentImplementation.superclassImplementation().isPresent()) {
-      // Partial child implementations that have no new cancellations don't need to override
-      // the method just to call super().
-      return;
-    }
-
-    componentImplementation.addMethod(CANCELLATION_LISTENER_METHOD, methodBuilder.build());
-  }
-
-  private ImmutableList<CodeBlock> cancellationStatements() {
-    // Reversing should order cancellations starting from entry points and going down to leaves
-    // rather than the other way around. This shouldn't really matter but seems *slightly*
-    // preferable because:
-    // When a future that another future depends on is cancelled, that cancellation will propagate
-    // up the future graph toward the entry point. Cancelling in reverse order should ensure that
-    // everything that depends on a particular node has already been cancelled when that node is
-    // cancelled, so there's no need to propagate. Otherwise, when we cancel a leaf node, it might
-    // propagate through most of the graph, making most of the cancel calls that follow in the
-    // onProducerFutureCancelled method do nothing.
-    ImmutableList<Key> cancellationKeys =
-        componentImplementation.getCancellableProducerKeys().reverse();
-
-    ImmutableList.Builder<CodeBlock> cancellationStatements = ImmutableList.builder();
-    for (Key cancellationKey : cancellationKeys) {
-      cancellationStatements.add(
-          CodeBlock.of(
-              "$T.cancel($L, $N);",
-              Producers.class,
-              bindingExpressions
-                  .getDependencyExpression(
-                      bindingRequest(cancellationKey, FrameworkType.PRODUCER_NODE),
-                      componentImplementation.name())
-                  .codeBlock(),
-              MAY_INTERRUPT_IF_RUNNING));
-    }
-    return cancellationStatements.build();
-  }
-
-  protected Optional<CodeBlock> cancelParentStatement() {
-    // Returns empty by default. Overridden in subclass(es) to add a statement if and only if the
-    // component being generated is a concrete subcomponent implementation with a parent that
-    // allows cancellation to propagate to it from subcomponents.
-    return Optional.empty();
-  }
-
-  /**
-   * For final components, reimplements all modifiable module methods that may have been modified.
-   */
-  private void implementModifiableModuleMethods() {
-    if (componentImplementation.isAbstract()) {
-      return;
-    }
-    componentImplementation
-        .getAllModifiableModuleMethods()
-        .forEach(this::implementModifiableModuleMethod);
-  }
-
-  private void implementModifiableModuleMethod(ComponentRequirement module, String methodName) {
-    // TODO(b/117833324): only reimplement methods for modules that were abstract or were repeated
-    // by an ancestor component.
-    componentImplementation.addMethod(
-        MODIFIABLE_BINDING_METHOD,
-        methodBuilder(methodName)
-            .addAnnotation(Override.class)
-            .addModifiers(PROTECTED)
-            .returns(TypeName.get(module.type()))
-            .addStatement(
-                componentRequirementExpressions
-                    .getExpression(module)
-                    .getModifiableModuleMethodExpression(componentImplementation.name()))
-            .build());
-  }
-
-  private MethodSignature getMethodSignature(ComponentMethodDescriptor method) {
-    return MethodSignature.forComponentMethod(
-        method, MoreTypes.asDeclared(graph.componentTypeElement().asType()), types);
-  }
-
-  private void addChildComponents() {
-    for (BindingGraph subgraph : graph.subgraphs()) {
-      // TODO(b/117833324): Can an abstract inner subcomponent implementation be elided if it's
-      // totally empty?
-      componentImplementation.addChild(
-          subgraph.componentDescriptor(), buildChildImplementation(subgraph));
-    }
-  }
-
-  private ComponentImplementation buildChildImplementation(BindingGraph childGraph) {
-    ComponentImplementation childImplementation =
-        compilerOptions.aheadOfTimeSubcomponents()
-            ? abstractInnerSubcomponent(childGraph)
-            : concreteSubcomponent(childGraph);
-    return topLevelImplementationComponent
-        .currentImplementationSubcomponentBuilder()
-        .componentImplementation(childImplementation)
-        .bindingGraph(childGraph)
-        .parentBuilder(Optional.of(this))
-        .parentBindingExpressions(Optional.of(bindingExpressions))
-        .parentRequirementExpressions(Optional.of(componentRequirementExpressions))
-        .build()
-        .subcomponentBuilder()
-        .build();
-  }
-
-  /** Creates an inner abstract subcomponent implementation. */
-  private ComponentImplementation abstractInnerSubcomponent(BindingGraph childGraph) {
-    return componentImplementation.childComponentImplementation(
-        childGraph,
-        Optional.of(
-            componentImplementationFactory.findChildSuperclassImplementation(
-                childGraph.componentDescriptor(), componentImplementation)),
-        PROTECTED,
-        componentImplementation.isAbstract() ? ABSTRACT : FINAL);
-  }
-
-  /** Creates a concrete inner subcomponent implementation. */
-  private ComponentImplementation concreteSubcomponent(BindingGraph childGraph) {
-    return componentImplementation.childComponentImplementation(
-        childGraph,
-        Optional.empty(), // superclassImplementation
-        PRIVATE,
-        FINAL);
-  }
-
-  /** Creates and adds the constructor and methods needed for initializing the component. */
-  private void addConstructorAndInitializationMethods() {
-    MethodSpec.Builder constructor = componentConstructorBuilder();
-    if (!componentImplementation.isAbstract()) {
-      implementInitializationMethod(constructor, initializationParameters());
-    } else if (componentImplementation.hasInitializations()) {
-      addConfigureInitializationMethod();
-    }
-    componentImplementation.addMethod(CONSTRUCTOR, constructor.build());
-  }
-
-  /** Returns a builder for the component's constructor. */
-  private MethodSpec.Builder componentConstructorBuilder() {
-    return constructorBuilder()
-            .addModifiers(componentImplementation.isAbstract() ? PROTECTED : PRIVATE);
-  }
-
-  /** Adds parameters and code to the given {@code initializationMethod}. */
-  private void implementInitializationMethod(
-      MethodSpec.Builder initializationMethod,
-      ImmutableMap<ComponentRequirement, ParameterSpec> initializationParameters) {
-    initializationMethod.addParameters(initializationParameters.values());
-    initializationMethod.addCode(
-        CodeBlocks.concat(componentImplementation.getComponentRequirementInitializations()));
-    componentImplementation
-        .superConfigureInitializationMethod()
-        .ifPresent(
-            superConfigureInitializationMethod ->
-                addSuperConfigureInitializationCall(
-                    initializationMethod,
-                    initializationParameters,
-                    superConfigureInitializationMethod));
-    addInitializeMethods(initializationMethod, initializationParameters.values().asList());
-  }
-
-  /** Creates and adds a {@code configureInitializatoin} method to the component. */
-  private void addConfigureInitializationMethod() {
-    MethodSpec.Builder method = configureInitializationMethodBuilder();
-    ImmutableMap<ComponentRequirement, ParameterSpec> parameters = initializationParameters();
-    implementInitializationMethod(method, parameters);
-    componentImplementation.setConfigureInitializationMethod(
-        ConfigureInitializationMethod.create(method.build(), parameters.keySet()));
-  }
-
-  /** Returns a builder for the component's {@code configureInitialization} method. */
-  private MethodSpec.Builder configureInitializationMethodBuilder() {
-    String methodName = componentImplementation.getUniqueMethodName("configureInitialization");
-    MethodSpec.Builder configureInitialization = methodBuilder(methodName).addModifiers(PROTECTED);
-    if (overridesSuperclassConfigureInitialization(configureInitialization.build())) {
-      configureInitialization.addAnnotation(Override.class);
-    }
-    return configureInitialization;
-  }
-
-  /**
-   * Returns whether or not the given method overrides a configureInitialization method from a
-   * superclass.
-   */
-  private boolean overridesSuperclassConfigureInitialization(MethodSpec method) {
-    for (Optional<ComponentImplementation> currentSuperImplementation =
-            componentImplementation.superclassImplementation();
-        currentSuperImplementation.isPresent();
-        currentSuperImplementation = currentSuperImplementation.get().superclassImplementation()) {
-      Optional<MethodSpec> superConfigureInitializationMethod =
-          currentSuperImplementation.get().configureInitializationMethod().map(m -> m.spec());
-      if (superConfigureInitializationMethod
-          .filter(superMethod -> haveSameSignature(method, superMethod))
-          .isPresent()) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /** Returns whether or not methods {@code a} and {@code b} have the same signature. */
-  private boolean haveSameSignature(MethodSpec a, MethodSpec b) {
-    return a.name.equals(b.name) && types(a.parameters).equals(types(b.parameters));
-  }
-
-  private ImmutableList<TypeName> types(List<ParameterSpec> parameters) {
-    return parameters.stream().map(parameter -> parameter.type).collect(toImmutableList());
-  }
-
-  /**
-   * Adds a call to the superclass's {@code configureInitialization} method to the given {@code
-   * callingMethod}.
-   */
-  private void addSuperConfigureInitializationCall(
-      MethodSpec.Builder callingMethod,
-      ImmutableMap<ComponentRequirement, ParameterSpec> parameters,
-      ConfigureInitializationMethod superConfigureInitializationMethod) {
-    // This component's constructor may not have all of the parameters that the superclass's
-    // configureInitialization method takes, because the superclass configureInitialization method
-    // necessarily accepts things that it can't know whether will be needed or not. If they aren't
-    // needed (as is the case when the constructor doesn't have a parameter for the module), just
-    // pass null to super.configureInitialization for that parameter; it won't be used.
-    CodeBlock args =
-        superConfigureInitializationMethod.parameters().stream()
-            .map(
-                requirement ->
-                    parameters.containsKey(requirement)
-                        ? CodeBlock.of("$N", parameters.get(requirement))
-                        : CodeBlock.of("null"))
-            .collect(toParametersCodeBlock());
-
-    String qualifier =
-        haveSameSignature(callingMethod.build(), superConfigureInitializationMethod.spec())
-            ? "super."
-            : "";
-    callingMethod.addStatement(
-        qualifier + "$N($L)", superConfigureInitializationMethod.spec(), args);
-  }
-
-  /**
-   * Adds any necessary {@code initialize} methods to the component and adds calls to them to the
-   * given {@code callingMethod}.
-   */
-  private void addInitializeMethods(
-      MethodSpec.Builder callingMethod, ImmutableList<ParameterSpec> parameters) {
-    // TODO(cgdecker): It's not the case that each initialize() method has need for all of the
-    // given parameters. In some cases, those parameters may have already been assigned to fields
-    // which could be referenced instead. In other cases, an initialize method may just not need
-    // some of the parameters because the set of initializations in that partition does not
-    // include any reference to them. Right now, the Dagger code has no way of getting that
-    // information because, among other things, componentImplementation.getImplementations() just
-    // returns a bunch of CodeBlocks with no semantic information. Additionally, we may not know
-    // yet whether a field will end up needing to be created for a specific requirement, and we
-    // don't want to create a field that ends up only being used during initialization.
-    CodeBlock args = parameterNames(parameters);
-    ImmutableList<MethodSpec> methods =
-        createPartitionedMethods(
-            "initialize",
-            makeFinal(parameters),
-            componentImplementation.getInitializations(),
-            methodName ->
-                methodBuilder(methodName)
-                    .addModifiers(PRIVATE)
-                    /* TODO(gak): Strictly speaking, we only need the suppression here if we are
-                     * also initializing a raw field in this method, but the structure of this
-                     * code makes it awkward to pass that bit through.  This will be cleaned up
-                     * when we no longer separate fields and initialization as we do now. */
-                    .addAnnotation(AnnotationSpecs.suppressWarnings(UNCHECKED)));
-    for (MethodSpec method : methods) {
-      callingMethod.addStatement("$N($L)", method, args);
-      componentImplementation.addMethod(INITIALIZE_METHOD, method);
-    }
-  }
-
-  /**
-   * Creates one or more methods, all taking the given {@code parameters}, which partition the given
-   * list of {@code statements} among themselves such that no method has more than {@code
-   * STATEMENTS_PER_METHOD} statements in it and such that the returned methods, if called in order,
-   * will execute the {@code statements} in the given order.
-   */
-  private ImmutableList<MethodSpec> createPartitionedMethods(
-      String methodName,
-      Iterable<ParameterSpec> parameters,
-      List<CodeBlock> statements,
-      Function<String, MethodSpec.Builder> methodBuilderCreator) {
-    return Lists.partition(statements, STATEMENTS_PER_METHOD).stream()
-        .map(
-            partition ->
-                methodBuilderCreator
-                    .apply(componentImplementation.getUniqueMethodName(methodName))
-                    .addParameters(parameters)
-                    .addCode(CodeBlocks.concat(partition))
-                    .build())
-        .collect(toImmutableList());
-  }
-
-  /** Returns the given parameters with a final modifier added. */
-  private final ImmutableList<ParameterSpec> makeFinal(Collection<ParameterSpec> parameters) {
-    return parameters.stream()
-        .map(param -> param.toBuilder().addModifiers(FINAL).build())
-        .collect(toImmutableList());
-  }
-
-  /**
-   * Returns the parameters for the constructor or {@code configureInitilization} method as a map
-   * from the requirement the parameter fulfills to the spec for the parameter.
-   */
-  private final ImmutableMap<ComponentRequirement, ParameterSpec> initializationParameters() {
-    Map<ComponentRequirement, ParameterSpec> parameters;
-    if (componentImplementation.componentDescriptor().hasCreator()) {
-      parameters =
-          Maps.toMap(componentImplementation.requirements(), ComponentRequirement::toParameterSpec);
-    } else if (componentImplementation.isAbstract() && componentImplementation.isNested()) {
-      // If we're generating an abstract inner subcomponent, then we are not implementing module
-      // instance bindings and have no need for factory method parameters.
-      parameters = ImmutableMap.of();
-    } else if (graph.factoryMethod().isPresent()) {
-      parameters = getFactoryMethodParameters(graph);
-    } else if (componentImplementation.isAbstract()) {
-      // If we're generating an abstract base implementation of a subcomponent it's acceptable to
-      // have neither a creator nor factory method.
-      parameters = ImmutableMap.of();
-    } else {
-      throw new AssertionError(
-          "Expected either a component creator or factory method but found neither.");
-    }
-
-    if (componentImplementation.isAbstract()) {
-      parameters = Maps.filterKeys(parameters, in(configureInitializationRequirements()));
-    }
-    return renameParameters(parameters);
-  }
-
-  /**
-   * Returns the set of requirements for the configureInitialization method: the parameters that are
-   * needed either for initializing a component requirement field or for calling the superclass's
-   * {@code configureInitialization} method.
-   */
-  private ImmutableSet<ComponentRequirement> configureInitializationRequirements() {
-    ImmutableSet<ComponentRequirement> initializationParameters =
-        componentImplementation.getComponentRequirementParameters();
-    ImmutableSet<ComponentRequirement> superConfigureInitializationRequirements =
-        componentImplementation
-            .superConfigureInitializationMethod()
-            .map(ConfigureInitializationMethod::parameters)
-            .orElse(ImmutableSet.of());
-    return Sets.union(initializationParameters, superConfigureInitializationRequirements)
-        .immutableCopy();
-  }
-
-  /**
-   * Renames the given parameters to guarantee their names do not conflict with fields in the
-   * component to ensure that a parameter is never referenced where a reference to a field was
-   * intended.
-   */
-  // TODO(cgdecker): This is a bit kludgy; it would be preferable to either qualify the field
-  // references with "this." or "super." when needed to disambiguate between field and parameter,
-  // but that would require more context than is currently available when the code referencing a
-  // field is generated.
-  private ImmutableMap<ComponentRequirement, ParameterSpec> renameParameters(
-      Map<ComponentRequirement, ParameterSpec> parameters) {
-    return ImmutableMap.copyOf(
-        Maps.transformEntries(
-            parameters,
-            (requirement, parameter) ->
-                renameParameter(
-                    parameter,
-                    componentImplementation.getParameterName(requirement, parameter.name))));
-  }
-
-  private ParameterSpec renameParameter(ParameterSpec parameter, String newName) {
-    return ParameterSpec.builder(parameter.type, newName)
-        .addAnnotations(parameter.annotations)
-        .addModifiers(parameter.modifiers)
-        .build();
-  }
-
-  /** Builds a root component implementation. */
-  static final class RootComponentImplementationBuilder extends ComponentImplementationBuilder {
-    @Inject
-    RootComponentImplementationBuilder(ComponentImplementation componentImplementation) {
-      checkArgument(!componentImplementation.superclassImplementation().isPresent());
-    }
-
-    @Override
-    protected void addCreatorClass(TypeSpec creator) {
-      componentImplementation.addType(COMPONENT_CREATOR, creator);
-    }
-
-    @Override
-    protected void addFactoryMethods() {
-      // Top-level components have a static method that returns a builder or factory for the
-      // component. If the user defined a @Component.Builder or @Component.Factory, an
-      // implementation of their type is returned. Otherwise, an autogenerated Builder type is
-      // returned.
-      // TODO(cgdecker): Replace this abomination with a small class?
-      // Better yet, change things so that an autogenerated builder type has a descriptor of sorts
-      // just like a user-defined creator type.
-      ComponentCreatorKind creatorKind;
-      ClassName creatorType;
-      String factoryMethodName;
-      boolean noArgFactoryMethod;
-      if (creatorDescriptor().isPresent()) {
-        ComponentCreatorDescriptor descriptor = creatorDescriptor().get();
-        creatorKind = descriptor.kind();
-        creatorType = ClassName.get(descriptor.typeElement());
-        factoryMethodName = descriptor.factoryMethod().getSimpleName().toString();
-        noArgFactoryMethod = descriptor.factoryParameters().isEmpty();
-      } else {
-        creatorKind = BUILDER;
-        creatorType = componentCreatorName();
-        factoryMethodName = "build";
-        noArgFactoryMethod = true;
-      }
-
-      MethodSpec creatorFactoryMethod =
-          methodBuilder(creatorKind.methodName())
-              .addModifiers(PUBLIC, STATIC)
-              .returns(creatorType)
-              .addStatement("return new $T()", componentCreatorName())
-              .build();
-      componentImplementation.addMethod(BUILDER_METHOD, creatorFactoryMethod);
-      if (noArgFactoryMethod && canInstantiateAllRequirements()) {
-        componentImplementation.addMethod(
-            BUILDER_METHOD,
-            methodBuilder("create")
-                .returns(ClassName.get(super.graph.componentTypeElement()))
-                .addModifiers(PUBLIC, STATIC)
-                .addStatement(
-                    "return new $L().$L()", creatorKind.typeName(), factoryMethodName)
-                .build());
-      }
-    }
-
-    private Optional<ComponentCreatorDescriptor> creatorDescriptor() {
-      return graph.componentDescriptor().creatorDescriptor();
-    }
-
-    /** {@code true} if all of the graph's required dependencies can be automatically constructed */
-    private boolean canInstantiateAllRequirements() {
-      return !Iterables.any(
-          graph.componentRequirements(),
-          dependency -> dependency.requiresAPassedInstance(elements, types));
-    }
-
-    private ClassName componentCreatorName() {
-      return componentImplementation.creatorImplementation().get().name();
-    }
-  }
-
-  /**
-   * Builds a subcomponent implementation. If generating ahead-of-time subcomponents, this may be an
-   * abstract base class implementation, an abstract inner implementation, or a concrete
-   * implementation that extends an abstract base implementation. Otherwise it represents a private,
-   * inner, concrete, final implementation of a subcomponent which extends a user defined type.
-   */
-  static final class SubcomponentImplementationBuilder extends ComponentImplementationBuilder {
-    final Optional<ComponentImplementationBuilder> parent;
-
-    @Inject
-    SubcomponentImplementationBuilder(
-        @ParentComponent Optional<ComponentImplementationBuilder> parent) {
-      this.parent = parent;
-    }
-
-    @Override
-    protected void addCreatorClass(TypeSpec creator) {
-      if (parent.isPresent()) {
-        // In an inner implementation of a subcomponent the creator is a peer class.
-        parent.get().componentImplementation.addType(SUBCOMPONENT, creator);
-      } else {
-        componentImplementation.addType(SUBCOMPONENT, creator);
-      }
-    }
-
-    @Override
-    protected void addFactoryMethods() {
-      // Only construct instances of subcomponents that have concrete implementations.
-      if (!componentImplementation.isAbstract()) {
-        // Use the parent's factory method to create this subcomponent if the
-        // subcomponent was not added via {@link dagger.Module#subcomponents()}.
-        graph.factoryMethod().ifPresent(this::createSubcomponentFactoryMethod);
-      }
-    }
-
-    private void createSubcomponentFactoryMethod(ExecutableElement factoryMethod) {
-      checkState(parent.isPresent());
-
-      Collection<ParameterSpec> params = getFactoryMethodParameters(graph).values();
-      MethodSpec.Builder method = MethodSpec.overriding(factoryMethod, parentType(), types);
-      params.forEach(
-          param -> method.addStatement("$T.checkNotNull($N)", Preconditions.class, param));
-      method.addStatement(
-          "return new $T($L)", componentImplementation.name(), parameterNames(params));
-
-      parent.get().componentImplementation.addMethod(COMPONENT_METHOD, method.build());
-    }
-
-    private DeclaredType parentType() {
-      return asDeclared(parent.get().graph.componentTypeElement().asType());
-    }
-
-    @Override
-    protected void addInterfaceMethods() {
-      if (componentImplementation.superclassImplementation().isPresent()) {
-        // Since we're overriding a subcomponent implementation we add to its implementation given
-        // an expanded binding graph.
-
-        ComponentImplementation superclassImplementation =
-            componentImplementation.superclassImplementation().get();
-        for (ModifiableBindingMethod superclassModifiableBindingMethod :
-            superclassImplementation.getModifiableBindingMethods().values()) {
-          bindingExpressions
-              .modifiableBindingExpressions()
-              .possiblyReimplementedMethod(superclassModifiableBindingMethod)
-              .ifPresent(componentImplementation::addImplementedModifiableBindingMethod);
-        }
-      } else {
-        super.addInterfaceMethods();
-      }
-    }
-
-    @Override
-    protected Optional<CodeBlock> cancelParentStatement() {
-      if (!shouldPropagateCancellationToParent()) {
-        return Optional.empty();
-      }
-      return Optional.of(
-          CodeBlock.builder()
-              .addStatement(
-                  "$T.this.$N($N)",
-                  parent.get().componentImplementation.name(),
-                  CANCELLATION_LISTENER_METHOD_NAME,
-                  MAY_INTERRUPT_IF_RUNNING)
-              .build());
-    }
-
-    private boolean shouldPropagateCancellationToParent() {
-      return parent.isPresent()
-          && parent
-              .get()
-              .componentImplementation
-              .componentDescriptor()
-              .cancellationPolicy()
-              .map(policy -> policy.fromSubcomponents().equals(PROPAGATE))
-              .orElse(false);
-    }
-  }
-
-  /**
-   * Returns the map of {@link ComponentRequirement}s to {@link ParameterSpec}s for the
-   * given graph's factory method.
-   */
-  private static Map<ComponentRequirement, ParameterSpec> getFactoryMethodParameters(
-      BindingGraph graph) {
-    return Maps.transformValues(graph.factoryMethodParameters(), ParameterSpec::get);
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentImplementationFactory.java b/java/dagger/internal/codegen/ComponentImplementationFactory.java
deleted file mode 100644
index 9578ece..0000000
--- a/java/dagger/internal/codegen/ComponentImplementationFactory.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkState;
-import static dagger.internal.codegen.ComponentGenerator.componentName;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static javax.tools.Diagnostic.Kind.WARNING;
-
-import com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.serialization.ProtoSerialization.InconsistentSerializedProtoException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.lang.model.element.TypeElement;
-
-/** Factory for {@link ComponentImplementation}s. */
-@Singleton
-final class ComponentImplementationFactory implements ClearableCache {
-  private final Map<TypeElement, ComponentImplementation> topLevelComponentCache = new HashMap<>();
-  private final KeyFactory keyFactory;
-  private final CompilerOptions compilerOptions;
-  private final BindingGraphFactory bindingGraphFactory;
-  private final TopLevelImplementationComponent.Builder topLevelImplementationComponentBuilder;
-  private final DeserializedComponentImplementationBuilder
-      deserializedComponentImplementationBuilder;
-  private final DaggerElements elements;
-  private final Messager messager;
-
-  @Inject
-  ComponentImplementationFactory(
-      KeyFactory keyFactory,
-      CompilerOptions compilerOptions,
-      BindingGraphFactory bindingGraphFactory,
-      TopLevelImplementationComponent.Builder topLevelImplementationComponentBuilder,
-      DeserializedComponentImplementationBuilder deserializedComponentImplementationBuilder,
-      DaggerElements elements,
-      Messager messager) {
-    this.keyFactory = keyFactory;
-    this.compilerOptions = compilerOptions;
-    this.bindingGraphFactory = bindingGraphFactory;
-    this.topLevelImplementationComponentBuilder = topLevelImplementationComponentBuilder;
-    this.deserializedComponentImplementationBuilder = deserializedComponentImplementationBuilder;
-    this.elements = elements;
-    this.messager = messager;
-  }
-
-  /**
-   * Returns a top-level (non-nested) component implementation for a binding graph.
-   *
-   * @throws IllegalStateException if the binding graph is for a subcomponent and
-   *     ahead-of-time-subcomponents mode is not enabled
-   */
-  ComponentImplementation createComponentImplementation(BindingGraph bindingGraph) {
-    return reentrantComputeIfAbsent(
-        topLevelComponentCache,
-        bindingGraph.componentTypeElement(),
-        component -> createComponentImplementationUncached(bindingGraph));
-  }
-
-  private ComponentImplementation createComponentImplementationUncached(BindingGraph bindingGraph) {
-    ComponentImplementation componentImplementation =
-        ComponentImplementation.topLevelComponentImplementation(
-            bindingGraph,
-            componentName(bindingGraph.componentTypeElement()),
-            new SubcomponentNames(bindingGraph, keyFactory),
-            compilerOptions);
-
-    // TODO(dpb): explore using optional bindings for the "parent" bindings
-    CurrentImplementationSubcomponent currentImplementationSubcomponent =
-        topLevelImplementationComponentBuilder
-            .topLevelComponent(componentImplementation)
-            .build()
-            .currentImplementationSubcomponentBuilder()
-            .componentImplementation(componentImplementation)
-            .bindingGraph(bindingGraph)
-            .parentBuilder(Optional.empty())
-            .parentBindingExpressions(Optional.empty())
-            .parentRequirementExpressions(Optional.empty())
-            .build();
-
-    if (componentImplementation.isAbstract()) {
-      checkState(
-          compilerOptions.aheadOfTimeSubcomponents(),
-          "Calling 'componentImplementation()' on %s when not generating ahead-of-time "
-              + "subcomponents.",
-          bindingGraph.componentTypeElement());
-      return currentImplementationSubcomponent.subcomponentBuilder().build();
-    } else {
-      return currentImplementationSubcomponent.rootComponentBuilder().build();
-    }
-  }
-
-  /** Returns the superclass of the child nested within a superclass of the parent component. */
-  ComponentImplementation findChildSuperclassImplementation(
-      ComponentDescriptor child, ComponentImplementation parentImplementation) {
-    // If the current component has superclass implementations, a superclass may contain a
-    // reference to the child. Traverse this component's superimplementation hierarchy looking for
-    // the child's implementation. The child superclass implementation may not be present in the
-    // direct superclass implementations if the subcomponent builder was previously a pruned
-    // binding.
-    for (Optional<ComponentImplementation> parent = parentImplementation.superclassImplementation();
-        parent.isPresent();
-        parent = parent.get().superclassImplementation()) {
-      Optional<ComponentImplementation> superclass = parent.get().childImplementation(child);
-      if (superclass.isPresent()) {
-        return superclass.get();
-      }
-    }
-
-    if (compilerOptions.emitModifiableMetadataAnnotations()) {
-      ClassName childSuperclassName = componentName(child.typeElement());
-      TypeElement generatedChildSuperclassImplementation =
-          elements.getTypeElement(childSuperclassName);
-      if (generatedChildSuperclassImplementation != null) {
-        try {
-          return deserializedComponentImplementationBuilder.create(
-              child, generatedChildSuperclassImplementation);
-        } catch (InconsistentSerializedProtoException e) {
-          messager.printMessage(
-              WARNING,
-              String.format(
-                  "%s was compiled with a different version of Dagger than the version in this "
-                      + "compilation. To ensure the validity of Dagger's generated code, compile "
-                      + "all Dagger code with the same version.",
-                  child.typeElement().getQualifiedName()));
-        }
-      } else if (compilerOptions.forceUseSerializedComponentImplementations()) {
-        throw new TypeNotPresentException(childSuperclassName.toString(), null);
-      }
-    }
-
-    // Otherwise, the superclass implementation is top-level, so we must recreate the
-    // implementation object for the base implementation of the child by truncating the binding
-    // graph at the child.
-    BindingGraph truncatedBindingGraph = bindingGraphFactory.create(child, false);
-    return createComponentImplementation(truncatedBindingGraph);
-  }
-
-  @Override
-  public void clearCache() {
-    topLevelComponentCache.clear();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java b/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java
deleted file mode 100644
index e98d595..0000000
--- a/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.javapoet.Expression;
-
-/** A binding expression for the instance of the component itself, i.e. {@code this}. */
-final class ComponentInstanceBindingExpression extends SimpleInvocationBindingExpression {
-  private final ClassName componentName;
-  private final ContributionBinding binding;
-
-  ComponentInstanceBindingExpression(ResolvedBindings resolvedBindings, ClassName componentName) {
-    super(resolvedBindings);
-    this.componentName = componentName;
-    this.binding = resolvedBindings.contributionBinding();
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    return Expression.create(
-        binding.key().type(),
-        componentName.equals(requestingClass)
-            ? CodeBlock.of("this")
-            : CodeBlock.of("$T.this", componentName));
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentKind.java b/java/dagger/internal/codegen/ComponentKind.java
deleted file mode 100644
index 8e5b9ba..0000000
--- a/java/dagger/internal/codegen/ComponentKind.java
+++ /dev/null
@@ -1,170 +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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.collect.Sets.immutableEnumSet;
-import static dagger.internal.codegen.DaggerStreams.stream;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.valuesOf;
-import static java.util.EnumSet.allOf;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.Component;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import javax.lang.model.element.TypeElement;
-
-/** Enumeration of the different kinds of components. */
-enum ComponentKind {
-  /** {@code @Component} */
-  COMPONENT(Component.class, true, false),
-
-  /** {@code @Subcomponent} */
-  SUBCOMPONENT(Subcomponent.class, false, false),
-
-  /** {@code @ProductionComponent} */
-  PRODUCTION_COMPONENT(ProductionComponent.class, true, true),
-
-  /** {@code @ProductionSubcomponent} */
-  PRODUCTION_SUBCOMPONENT(ProductionSubcomponent.class, false, true),
-
-  /**
-   * Kind for a descriptor that was generated from a {@link Module} instead of a component type in
-   * order to validate the module's bindings.
-   */
-  MODULE(Module.class, true, false),
-
-  /**
-   * Kind for a descriptor was generated from a {@link ProducerModule} instead of a component type
-   * in order to validate the module's bindings.
-   */
-  PRODUCER_MODULE(ProducerModule.class, true, true),
-  ;
-
-  private static final ImmutableSet<ComponentKind> ROOT_COMPONENT_KINDS =
-      valuesOf(ComponentKind.class)
-          .filter(kind -> !kind.isForModuleValidation())
-          .filter(kind -> kind.isRoot())
-          .collect(toImmutableSet());
-
-  private static final ImmutableSet<ComponentKind> SUBCOMPONENT_KINDS =
-      valuesOf(ComponentKind.class)
-          .filter(kind -> !kind.isForModuleValidation())
-          .filter(kind -> !kind.isRoot())
-          .collect(toImmutableSet());
-
-  /** Returns the set of kinds for root components. */
-  static ImmutableSet<ComponentKind> rootComponentKinds() {
-    return ROOT_COMPONENT_KINDS;
-  }
-
-  /** Returns the set of kinds for subcomponents. */
-  static ImmutableSet<ComponentKind> subcomponentKinds() {
-    return SUBCOMPONENT_KINDS;
-  }
-
-  /** Returns the annotations for components of the given kinds. */
-  static ImmutableSet<Class<? extends Annotation>> annotationsFor(Iterable<ComponentKind> kinds) {
-    return stream(kinds).map(ComponentKind::annotation).collect(toImmutableSet());
-  }
-
-  /** Returns the set of component kinds the given {@code element} has annotations for. */
-  static ImmutableSet<ComponentKind> getComponentKinds(TypeElement element) {
-    return valuesOf(ComponentKind.class)
-        .filter(kind -> isAnnotationPresent(element, kind.annotation()))
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the kind of an annotated element if it is annotated with one of the {@linkplain
-   * #annotation() annotations}.
-   *
-   * @throws IllegalArgumentException if the element is annotated with more than one of the
-   *     annotations
-   */
-  static Optional<ComponentKind> forAnnotatedElement(TypeElement element) {
-    ImmutableSet<ComponentKind> kinds = getComponentKinds(element);
-    if (kinds.size() > 1) {
-      throw new IllegalArgumentException(
-          element + " cannot be annotated with more than one of " + annotationsFor(kinds));
-    }
-    return kinds.stream().findAny();
-  }
-
-  private final Class<? extends Annotation> annotation;
-  private final boolean isRoot;
-  private final boolean production;
-
-  ComponentKind(
-      Class<? extends Annotation> annotation,
-      boolean isRoot,
-      boolean production) {
-    this.annotation = annotation;
-    this.isRoot = isRoot;
-    this.production = production;
-  }
-
-  /** Returns the annotation that marks a component of this kind. */
-  Class<? extends Annotation> annotation() {
-    return annotation;
-  }
-
-  /** Returns the kinds of modules that can be used with a component of this kind. */
-  ImmutableSet<ModuleKind> legalModuleKinds() {
-    return isProducer()
-        ? immutableEnumSet(allOf(ModuleKind.class))
-        : immutableEnumSet(ModuleKind.MODULE);
-  }
-
-  /** Returns the kinds of subcomponents a component of this kind can have. */
-  ImmutableSet<ComponentKind> legalSubcomponentKinds() {
-    return isProducer()
-        ? immutableEnumSet(PRODUCTION_SUBCOMPONENT)
-        : immutableEnumSet(SUBCOMPONENT, PRODUCTION_SUBCOMPONENT);
-  }
-
-  /**
-   * Returns {@code true} if the descriptor is for a root component (not a subcomponent) or is for
-   * {@linkplain #isForModuleValidation() module-validation}.
-   */
-  boolean isRoot() {
-    return isRoot;
-  }
-
-  /** Returns true if this is a production component. */
-  boolean isProducer() {
-    return production;
-  }
-
-  /** Returns {@code true} if the descriptor is for a module in order to validate its bindings. */
-  boolean isForModuleValidation() {
-    switch (this) {
-      case MODULE:
-      case PRODUCER_MODULE:
-        return true;
-      default:
-        // fall through
-    }
-    return false;
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentMethodBindingExpression.java b/java/dagger/internal/codegen/ComponentMethodBindingExpression.java
deleted file mode 100644
index 7e7bbd8..0000000
--- a/java/dagger/internal/codegen/ComponentMethodBindingExpression.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A binding expression that implements and uses a component method.
- *
- * <p>Dependents of this binding expression will just call the component method.
- */
-final class ComponentMethodBindingExpression extends MethodBindingExpression {
-  private final ComponentImplementation componentImplementation;
-  private final ComponentMethodDescriptor componentMethod;
-
-  ComponentMethodBindingExpression(
-      BindingRequest request,
-      ResolvedBindings resolvedBindings,
-      MethodImplementationStrategy methodImplementationStrategy,
-      BindingExpression wrappedBindingExpression,
-      ComponentImplementation componentImplementation,
-      ComponentMethodDescriptor componentMethod,
-      DaggerTypes types) {
-    super(
-        request,
-        resolvedBindings,
-        methodImplementationStrategy,
-        wrappedBindingExpression,
-        componentImplementation,
-        types);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentMethod = checkNotNull(componentMethod);
-  }
-
-  @Override
-  protected CodeBlock getComponentMethodImplementation(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    // There could be several methods on the component for the same request key and kind.
-    // Only one should use the BindingMethodImplementation; the others can delegate that one. So
-    // use methodImplementation.body() only if componentMethod equals the method for this instance.
-
-    // Separately, the method might be defined on a supertype that is also a supertype of some
-    // parent component. In that case, the same ComponentMethodDescriptor will be used to add a CMBE
-    // for the parent and the child. Only the parent's should use the BindingMethodImplementation;
-    // the child's can delegate to the parent. So use methodImplementation.body() only if
-    // componentName equals the component for this instance.
-    return componentMethod.equals(this.componentMethod) && component.equals(componentImplementation)
-        ? methodBodyForComponentMethod(componentMethod)
-        : super.getComponentMethodImplementation(componentMethod, component);
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    // If a component method returns a primitive, update the expression's type which might be boxed.
-    Expression expression = super.getDependencyExpression(requestingClass);
-    TypeMirror methodReturnType = componentMethod.methodElement().getReturnType();
-    return methodReturnType.getKind().isPrimitive()
-        ? Expression.create(methodReturnType, expression.codeBlock())
-        : expression;
-  }
-
-  @Override
-  protected void addMethod() {}
-
-  @Override
-  protected String methodName() {
-    return componentMethod.methodElement().getSimpleName().toString();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentNodeImpl.java b/java/dagger/internal/codegen/ComponentNodeImpl.java
deleted file mode 100644
index 3a31ec7..0000000
--- a/java/dagger/internal/codegen/ComponentNodeImpl.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableSet;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.ComponentPath;
-import dagger.model.DependencyRequest;
-import dagger.model.Scope;
-
-/** An implementation of {@link ComponentNode} that also exposes the {@link ComponentDescriptor}. */
-@AutoValue
-abstract class ComponentNodeImpl implements ComponentNode {
-  static ComponentNode create(
-      ComponentPath componentPath, ComponentDescriptor componentDescriptor) {
-    return new AutoValue_ComponentNodeImpl(componentPath, componentDescriptor);
-  }
-
-  @Override
-  public final boolean isSubcomponent() {
-    return componentDescriptor().isSubcomponent();
-  }
-
-  @Override
-  public boolean isRealComponent() {
-    return componentDescriptor().isRealComponent();
-  }
-
-  @Override
-  public final ImmutableSet<DependencyRequest> entryPoints() {
-    return componentDescriptor().entryPointMethods().stream()
-        .map(method -> method.dependencyRequest().get())
-        .collect(toImmutableSet());
-  }
-
-  @Override
-  public ImmutableSet<Scope> scopes() {
-    return componentDescriptor().scopes();
-  }
-
-  abstract ComponentDescriptor componentDescriptor();
-
-  @Override
-  public final String toString() {
-    return componentPath().toString();
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentProcessingStep.java b/java/dagger/internal/codegen/ComponentProcessingStep.java
deleted file mode 100644
index 645c94f..0000000
--- a/java/dagger/internal/codegen/ComponentProcessingStep.java
+++ /dev/null
@@ -1,278 +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.collect.Sets.union;
-import static dagger.internal.codegen.ComponentAnnotation.allComponentAnnotations;
-import static dagger.internal.codegen.ComponentAnnotation.rootComponentAnnotations;
-import static dagger.internal.codegen.ComponentAnnotation.subcomponentAnnotations;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.allCreatorAnnotations;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.rootComponentCreatorAnnotations;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.subcomponentCreatorAnnotations;
-import static dagger.internal.codegen.ValidationType.NONE;
-import static java.util.Collections.disjoint;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.auto.common.MoreElements;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import dagger.internal.codegen.ComponentValidator.ComponentValidationReport;
-import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A {@link ProcessingStep} that is responsible for dealing with a component or production component
- * as part of the {@link ComponentProcessor}.
- */
-final class ComponentProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
-  private final Messager messager;
-  private final ComponentValidator componentValidator;
-  private final ComponentCreatorValidator creatorValidator;
-  private final ComponentDescriptorValidator componentDescriptorValidator;
-  private final ComponentDescriptorFactory componentDescriptorFactory;
-  private final BindingGraphFactory bindingGraphFactory;
-  private final SourceFileGenerator<BindingGraph> componentGenerator;
-  private final BindingGraphConverter bindingGraphConverter;
-  private final BindingGraphValidator bindingGraphValidator;
-  private final CompilerOptions compilerOptions;
-  private ImmutableSet<Element> subcomponentElements;
-  private ImmutableSet<Element> subcomponentCreatorElements;
-  private ImmutableMap<Element, ValidationReport<TypeElement>> creatorReportsByComponent;
-  private ImmutableMap<Element, ValidationReport<TypeElement>> creatorReportsBySubcomponent;
-  private ImmutableMap<Element, ValidationReport<TypeElement>> reportsBySubcomponent;
-
-  @Inject
-  ComponentProcessingStep(
-      Messager messager,
-      ComponentValidator componentValidator,
-      ComponentCreatorValidator creatorValidator,
-      ComponentDescriptorValidator componentDescriptorValidator,
-      ComponentDescriptorFactory componentDescriptorFactory,
-      BindingGraphFactory bindingGraphFactory,
-      SourceFileGenerator<BindingGraph> componentGenerator,
-      BindingGraphConverter bindingGraphConverter,
-      BindingGraphValidator bindingGraphValidator,
-      CompilerOptions compilerOptions) {
-    super(MoreElements::asType);
-    this.messager = messager;
-    this.componentValidator = componentValidator;
-    this.creatorValidator = creatorValidator;
-    this.componentDescriptorValidator = componentDescriptorValidator;
-    this.componentDescriptorFactory = componentDescriptorFactory;
-    this.bindingGraphFactory = bindingGraphFactory;
-    this.componentGenerator = componentGenerator;
-    this.bindingGraphConverter = bindingGraphConverter;
-    this.bindingGraphValidator = bindingGraphValidator;
-    this.compilerOptions = compilerOptions;
-  }
-
-  @Override
-  public Set<Class<? extends Annotation>> annotations() {
-    return union(allComponentAnnotations(), allCreatorAnnotations());
-  }
-
-  @Override
-  public ImmutableSet<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    subcomponentElements =
-        getElementsFromAnnotations(elementsByAnnotation, subcomponentAnnotations());
-    subcomponentCreatorElements =
-        getElementsFromAnnotations(elementsByAnnotation, subcomponentCreatorAnnotations());
-
-    ImmutableSet.Builder<Element> rejectedElements = ImmutableSet.builder();
-
-    creatorReportsByComponent =
-        processCreators(
-            getElementsFromAnnotations(elementsByAnnotation, rootComponentCreatorAnnotations()),
-            rejectedElements);
-    creatorReportsBySubcomponent = processCreators(subcomponentCreatorElements, rejectedElements);
-    reportsBySubcomponent =
-        processSubcomponents(subcomponentElements, subcomponentCreatorElements, rejectedElements);
-
-    return rejectedElements.addAll(super.process(elementsByAnnotation)).build();
-  }
-
-  @Override
-  protected void process(
-      TypeElement element, ImmutableSet<Class<? extends Annotation>> annotations) {
-    if (!disjoint(annotations, rootComponentAnnotations())) {
-      processRootComponent(element);
-    }
-    if (!disjoint(annotations, subcomponentAnnotations())) {
-      processSubcomponent(element);
-    }
-  }
-
-  private void processRootComponent(TypeElement component) {
-    if (!isRootComponentValid(component)) {
-      return;
-    }
-    ComponentDescriptor componentDescriptor =
-        componentDescriptorFactory.rootComponentDescriptor(component);
-    if (!isValid(componentDescriptor)) {
-      return;
-    }
-    if (!isFullBindingGraphValid(componentDescriptor)) {
-      return;
-    }
-    BindingGraph bindingGraph = bindingGraphFactory.create(componentDescriptor, false);
-    if (isValid(bindingGraph)) {
-      generateComponent(bindingGraph);
-    }
-  }
-
-  private void processSubcomponent(TypeElement subcomponent) {
-    if (!compilerOptions.aheadOfTimeSubcomponents()
-        && compilerOptions.fullBindingGraphValidationType(subcomponent).equals(NONE)) {
-      return;
-    }
-    if (!isSubcomponentValid(subcomponent)) {
-      return;
-    }
-    ComponentDescriptor subcomponentDescriptor =
-        componentDescriptorFactory.subcomponentDescriptor(subcomponent);
-    // TODO(dpb): ComponentDescriptorValidator for subcomponents, as we do for root components.
-    if (!isFullBindingGraphValid(subcomponentDescriptor)) {
-      return;
-    }
-    if (compilerOptions.aheadOfTimeSubcomponents()) {
-      BindingGraph bindingGraph = bindingGraphFactory.create(subcomponentDescriptor, false);
-      if (isValid(bindingGraph)) {
-        generateComponent(bindingGraph);
-      }
-    }
-  }
-
-  private void generateComponent(BindingGraph bindingGraph) {
-    componentGenerator.generate(bindingGraph, messager);
-  }
-
-  static ImmutableSet<Element> getElementsFromAnnotations(
-      final SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation,
-      Set<Class<? extends Annotation>> annotations) {
-    return ImmutableSet.copyOf(
-        Multimaps.filterKeys(elementsByAnnotation, Predicates.in(annotations)).values());
-  }
-
-  private ImmutableMap<Element, ValidationReport<TypeElement>> processCreators(
-      Set<? extends Element> builderElements, ImmutableSet.Builder<Element> rejectedElements) {
-    // Can't use an ImmutableMap.Builder here because a component may have (invalidly) more than one
-    // builder type, and that would make ImmutableMap.Builder throw.
-    Map<Element, ValidationReport<TypeElement>> reports = new HashMap<>();
-    for (Element element : builderElements) {
-      try {
-        ValidationReport<TypeElement> report =
-            creatorValidator.validate(MoreElements.asType(element));
-        report.printMessagesTo(messager);
-        reports.put(element.getEnclosingElement(), report);
-      } catch (TypeNotPresentException e) {
-        rejectedElements.add(element);
-      }
-    }
-    return ImmutableMap.copyOf(reports);
-  }
-
-  private ImmutableMap<Element, ValidationReport<TypeElement>> processSubcomponents(
-      Set<? extends Element> subcomponentElements,
-      Set<? extends Element> subcomponentBuilderElements,
-      ImmutableSet.Builder<Element> rejectedElements) {
-    ImmutableMap.Builder<Element, ValidationReport<TypeElement>> reports = ImmutableMap.builder();
-    for (Element element : subcomponentElements) {
-      try {
-        ComponentValidationReport report =
-            componentValidator.validate(
-                MoreElements.asType(element), subcomponentElements, subcomponentBuilderElements);
-        report.report().printMessagesTo(messager);
-        reports.put(element, report.report());
-      } catch (TypeNotPresentException e) {
-        rejectedElements.add(element);
-      }
-    }
-    return reports.build();
-  }
-
-  private boolean isRootComponentValid(TypeElement rootComponent) {
-    ComponentValidationReport validationReport =
-        componentValidator.validate(
-            rootComponent, subcomponentElements, subcomponentCreatorElements);
-    validationReport.report().printMessagesTo(messager);
-    return isClean(validationReport);
-  }
-
-  // TODO(dpb): Clean up generics so this can take TypeElement.
-  private boolean isSubcomponentValid(Element subcomponentElement) {
-    ValidationReport<?> subcomponentCreatorReport =
-        creatorReportsBySubcomponent.get(subcomponentElement);
-    if (subcomponentCreatorReport != null && !subcomponentCreatorReport.isClean()) {
-      return false;
-    }
-    ValidationReport<?> subcomponentReport = reportsBySubcomponent.get(subcomponentElement);
-    return subcomponentReport == null || subcomponentReport.isClean();
-  }
-
-  private boolean isFullBindingGraphValid(ComponentDescriptor componentDescriptor) {
-    if (compilerOptions
-        .fullBindingGraphValidationType(componentDescriptor.typeElement())
-        .equals(NONE)) {
-      return true;
-    }
-    BindingGraph fullBindingGraph = bindingGraphFactory.create(componentDescriptor, true);
-    return isValid(fullBindingGraph);
-  }
-
-  private boolean isValid(ComponentDescriptor componentDescriptor) {
-    ValidationReport<TypeElement> componentDescriptorReport =
-        componentDescriptorValidator.validate(componentDescriptor);
-    componentDescriptorReport.printMessagesTo(messager);
-    return componentDescriptorReport.isClean();
-  }
-
-  private boolean isValid(BindingGraph bindingGraph) {
-    return bindingGraphValidator.isValid(bindingGraphConverter.convert(bindingGraph));
-  }
-
-  /**
-   * Returns true if the component's report is clean, its builder report is clean, and all
-   * referenced subcomponent reports and subcomponent builder reports are clean.
-   */
-  private boolean isClean(ComponentValidationReport report) {
-    Element component = report.report().subject();
-    ValidationReport<?> componentReport = report.report();
-    if (!componentReport.isClean()) {
-      return false;
-    }
-    ValidationReport<?> builderReport = creatorReportsByComponent.get(component);
-    if (builderReport != null && !builderReport.isClean()) {
-      return false;
-    }
-    for (Element element : report.referencedSubcomponents()) {
-      if (!isSubcomponentValid(element)) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentProcessor.java b/java/dagger/internal/codegen/ComponentProcessor.java
deleted file mode 100644
index 541a4ab..0000000
--- a/java/dagger/internal/codegen/ComponentProcessor.java
+++ /dev/null
@@ -1,203 +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 net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.DYNAMIC;
-
-import com.google.auto.common.BasicAnnotationProcessor;
-import com.google.auto.service.AutoService;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.BindsInstance;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.SpiModule.TestingPlugins;
-import dagger.spi.BindingGraphPlugin;
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.Set;
-import javax.annotation.processing.Processor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.lang.model.SourceVersion;
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
-
-/**
- * The annotation processor responsible for generating the classes that drive the Dagger 2.0
- * implementation.
- *
- * <p>TODO(gak): give this some better documentation
- */
-@IncrementalAnnotationProcessor(DYNAMIC)
-@AutoService(Processor.class)
-public class ComponentProcessor extends BasicAnnotationProcessor {
-  private final Optional<ImmutableSet<BindingGraphPlugin>> testingPlugins;
-
-  @Inject InjectBindingRegistry injectBindingRegistry;
-  @Inject SourceFileGenerator<ProvisionBinding> factoryGenerator;
-  @Inject SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator;
-  @Inject ImmutableList<ProcessingStep> processingSteps;
-  @Inject BindingGraphPlugins bindingGraphPlugins;
-  @Inject CompilerOptions compilerOptions;
-  @Inject DaggerStatisticsCollector statisticsCollector;
-  @Inject Set<ClearableCache> clearableCaches;
-
-  public ComponentProcessor() {
-    this.testingPlugins = Optional.empty();
-  }
-
-  private ComponentProcessor(Iterable<BindingGraphPlugin> testingPlugins) {
-    this.testingPlugins = Optional.of(ImmutableSet.copyOf(testingPlugins));
-  }
-
-  /**
-   * Creates a component processor that uses given {@link BindingGraphPlugin}s instead of loading
-   * them from a {@link java.util.ServiceLoader}.
-   */
-  @VisibleForTesting
-  public static ComponentProcessor forTesting(BindingGraphPlugin... testingPlugins) {
-    return forTesting(Arrays.asList(testingPlugins));
-  }
-
-  /**
-   * Creates a component processor that uses given {@link BindingGraphPlugin}s instead of loading
-   * them from a {@link java.util.ServiceLoader}.
-   */
-  @VisibleForTesting
-  public static ComponentProcessor forTesting(Iterable<BindingGraphPlugin> testingPlugins) {
-    return new ComponentProcessor(testingPlugins);
-  }
-
-  @Override
-  public SourceVersion getSupportedSourceVersion() {
-    return SourceVersion.latestSupported();
-  }
-
-  @Override
-  public Set<String> getSupportedOptions() {
-    ImmutableSet.Builder<String> options = ImmutableSet.builder();
-    options.addAll(ProcessingEnvironmentCompilerOptions.supportedOptions());
-    options.addAll(bindingGraphPlugins.allSupportedOptions());
-    if (compilerOptions.useGradleIncrementalProcessing()) {
-      options.add("org.gradle.annotation.processing.isolating");
-    }
-    return options.build();
-  }
-
-  @Override
-  protected Iterable<? extends ProcessingStep> initSteps() {
-    ProcessorComponent.builder()
-        .processingEnvironmentModule(new ProcessingEnvironmentModule(processingEnv))
-        .testingPlugins(testingPlugins)
-        .build()
-        .inject(this);
-
-    statisticsCollector.processingStarted();
-    bindingGraphPlugins.initializePlugins();
-    return Iterables.transform(
-        processingSteps,
-        step -> new DaggerStatisticsCollectingProcessingStep(step, statisticsCollector));
-  }
-
-  @Singleton
-  @Component(
-      modules = {
-        BindingGraphValidationModule.class,
-        BindingMethodValidatorsModule.class,
-        InjectBindingRegistryModule.class,
-        ProcessingEnvironmentModule.class,
-        ProcessingRoundCacheModule.class,
-        ProcessingStepsModule.class,
-        SourceFileGeneratorsModule.class,
-        SpiModule.class,
-        SystemComponentsModule.class,
-        TopLevelImplementationComponent.InstallationModule.class,
-      })
-  interface ProcessorComponent {
-    void inject(ComponentProcessor processor);
-
-    static Builder builder() {
-      return DaggerComponentProcessor_ProcessorComponent.builder();
-    }
-
-    @CanIgnoreReturnValue
-    @Component.Builder
-    interface Builder {
-      Builder processingEnvironmentModule(ProcessingEnvironmentModule module);
-
-      @BindsInstance
-      Builder testingPlugins(
-          @TestingPlugins Optional<ImmutableSet<BindingGraphPlugin>> testingPlugins);
-
-      @CheckReturnValue ProcessorComponent build();
-    }
-  }
-
-  @Module
-  interface ProcessingStepsModule {
-    @Provides
-    static ImmutableList<ProcessingStep> processingSteps(
-        MapKeyProcessingStep mapKeyProcessingStep,
-        InjectProcessingStep injectProcessingStep,
-        MonitoringModuleProcessingStep monitoringModuleProcessingStep,
-        MultibindingAnnotationsProcessingStep multibindingAnnotationsProcessingStep,
-        BindsInstanceProcessingStep bindsInstanceProcessingStep,
-        ModuleProcessingStep moduleProcessingStep,
-        ComponentProcessingStep componentProcessingStep,
-        ComponentHjarProcessingStep componentHjarProcessingStep,
-        BindingMethodProcessingStep bindingMethodProcessingStep,
-        CompilerOptions compilerOptions) {
-      return ImmutableList.of(
-          mapKeyProcessingStep,
-          injectProcessingStep,
-          monitoringModuleProcessingStep,
-          multibindingAnnotationsProcessingStep,
-          bindsInstanceProcessingStep,
-          moduleProcessingStep,
-          compilerOptions.headerCompilation()
-                  // Ahead Of Time subcomponents use the regular hjar filtering in
-                  // HjarSourceFileGenerator since they must retain protected implementation methods
-                  // between subcomponents
-                  && !compilerOptions.aheadOfTimeSubcomponents()
-              ? componentHjarProcessingStep
-              : componentProcessingStep,
-          bindingMethodProcessingStep);
-    }
-  }
-
-  @Override
-  protected void postRound(RoundEnvironment roundEnv) {
-    statisticsCollector.roundFinished();
-    if (roundEnv.processingOver()) {
-      statisticsCollector.processingStopped();
-    } else {
-      try {
-        injectBindingRegistry.generateSourcesForRequiredBindings(
-            factoryGenerator, membersInjectorGenerator);
-      } catch (SourceFileGenerationException e) {
-        e.printMessageTo(processingEnv.getMessager());
-      }
-    }
-    clearableCaches.forEach(ClearableCache::clearCache);
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java b/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java
deleted file mode 100644
index b8c6049..0000000
--- a/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.Preconditions;
-import dagger.internal.codegen.javapoet.Expression;
-
-/** A binding expression for component provision methods. */
-final class ComponentProvisionBindingExpression extends SimpleInvocationBindingExpression {
-  private final ProvisionBinding binding;
-  private final BindingGraph bindingGraph;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-  private final CompilerOptions compilerOptions;
-
-  ComponentProvisionBindingExpression(
-      ResolvedBindings resolvedBindings,
-      BindingGraph bindingGraph,
-      ComponentRequirementExpressions componentRequirementExpressions,
-      CompilerOptions compilerOptions) {
-    super(resolvedBindings);
-    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
-    this.bindingGraph = checkNotNull(bindingGraph);
-    this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions);
-    this.compilerOptions = checkNotNull(compilerOptions);
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    CodeBlock invocation =
-        CodeBlock.of(
-            "$L.$L()",
-            componentRequirementExpressions.getExpression(componentRequirement(), requestingClass),
-            binding.bindingElement().get().getSimpleName());
-    return Expression.create(
-        binding.contributedPrimitiveType().orElse(binding.key().type()),
-        maybeCheckForNull(binding, compilerOptions, invocation));
-  }
-
-  private ComponentRequirement componentRequirement() {
-    return bindingGraph
-        .componentDescriptor()
-        .getDependencyThatDefinesMethod(binding.bindingElement().get());
-  }
-
-  static CodeBlock maybeCheckForNull(
-      ProvisionBinding binding, CompilerOptions compilerOptions, CodeBlock invocation) {
-    return binding.shouldCheckForNull(compilerOptions)
-        ? CodeBlock.of(
-            "$T.checkNotNull($L, $S)",
-            Preconditions.class,
-            invocation,
-            "Cannot return null from a non-@Nullable component method")
-        : invocation;
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentRequirement.java b/java/dagger/internal/codegen/ComponentRequirement.java
deleted file mode 100644
index 3bed5da..0000000
--- a/java/dagger/internal/codegen/ComponentRequirement.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.MoreElements.getLocalAndInheritedMethods;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static dagger.internal.codegen.SourceFiles.simpleVariableName;
-import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.Binds;
-import dagger.BindsOptionalOf;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.internal.codegen.serialization.ComponentRequirementProto;
-import dagger.internal.codegen.serialization.ComponentRequirementProto.BoundInstanceRequirement;
-import dagger.model.BindingKind;
-import dagger.model.Key;
-import dagger.multibindings.Multibinds;
-import dagger.producers.Produces;
-import java.util.Optional;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A type that a component needs an instance of. */
-@AutoValue
-abstract class ComponentRequirement {
-  enum Kind {
-    /** A type listed in the component's {@code dependencies} attribute. */
-    DEPENDENCY,
-
-    /** A type listed in the component or subcomponent's {@code modules} attribute. */
-    MODULE,
-
-    /**
-     * An object that is passed to a builder's {@link dagger.BindsInstance @BindsInstance} method.
-     */
-    BOUND_INSTANCE,
-    ;
-
-    boolean isBoundInstance() {
-      return equals(BOUND_INSTANCE);
-    }
-
-    boolean isModule() {
-      return equals(MODULE);
-    }
-  }
-
-  /** The kind of requirement. */
-  abstract Kind kind();
-
-  /** Returns true if this is a {@link Kind#BOUND_INSTANCE} requirement. */
-  // TODO(ronshapiro): consider removing this and inlining the usages
-  final boolean isBoundInstance() {
-    return kind().isBoundInstance();
-  }
-
-  /**
-   * The type of the instance the component must have, wrapped so that requirements can be used as
-   * value types.
-   */
-  abstract Equivalence.Wrapper<TypeMirror> wrappedType();
-
-  /** The type of the instance the component must have. */
-  TypeMirror type() {
-    return wrappedType().get();
-  }
-
-  /** The element associated with the type of this requirement. */
-  TypeElement typeElement() {
-    return MoreTypes.asTypeElement(type());
-  }
-
-  /** The action a component builder should take if it {@code null} is passed. */
-  enum NullPolicy {
-    /** Make a new instance. */
-    NEW,
-    /** Throw an exception. */
-    THROW,
-    /** Allow use of null values. */
-    ALLOW,
-  }
-
-  /**
-   * An override for the requirement's null policy. If set, this is used as the null policy instead
-   * of the default behavior in {@link #nullPolicy}.
-   *
-   * <p>Some implementations' null policy can be determined upon construction (e.g., for binding
-   * instances), but others' require Elements and Types, which must wait until {@link #nullPolicy}
-   * is called.
-   */
-  abstract Optional<NullPolicy> overrideNullPolicy();
-
-  /** The requirement's null policy. */
-  NullPolicy nullPolicy(DaggerElements elements, DaggerTypes types) {
-    if (overrideNullPolicy().isPresent()) {
-      return overrideNullPolicy().get();
-    }
-    switch (kind()) {
-      case MODULE:
-        return componentCanMakeNewInstances(typeElement())
-            ? NullPolicy.NEW
-            : requiresAPassedInstance(elements, types) ? NullPolicy.THROW : NullPolicy.ALLOW;
-      case DEPENDENCY:
-      case BOUND_INSTANCE:
-        return NullPolicy.THROW;
-    }
-    throw new AssertionError();
-  }
-
-  /**
-   * Returns true if the passed {@link ComponentRequirement} requires a passed instance in order to
-   * be used within a component.
-   */
-  boolean requiresAPassedInstance(DaggerElements elements, DaggerTypes types) {
-    if (!kind().isModule()) {
-      // Bound instances and dependencies always require the user to provide an instance.
-      return true;
-    }
-    return requiresModuleInstance(elements, types) && !componentCanMakeNewInstances(typeElement());
-  }
-
-  /**
-   * Returns {@code true} if an instance is needed for this (module) requirement.
-   *
-   * <p>An instance is only needed if there is a binding method on the module that is neither {@code
-   * abstract} nor {@code static}; if all bindings are one of those, then there should be no
-   * possible dependency on instance state in the module's bindings.
-   */
-  private boolean requiresModuleInstance(DaggerElements elements, DaggerTypes types) {
-    ImmutableSet<ExecutableElement> methods =
-        getLocalAndInheritedMethods(typeElement(), types, elements);
-    return methods.stream()
-        .filter(this::isBindingMethod)
-        .map(ExecutableElement::getModifiers)
-        .anyMatch(modifiers -> !modifiers.contains(ABSTRACT) && !modifiers.contains(STATIC));
-  }
-
-  private boolean isBindingMethod(ExecutableElement method) {
-    // TODO(cgdecker): At the very least, we should have utility methods to consolidate this stuff
-    // in one place; listing individual annotations all over the place is brittle.
-    return isAnyAnnotationPresent(
-        method,
-        Provides.class,
-        Produces.class,
-        // TODO(ronshapiro): it would be cool to have internal meta-annotations that could describe
-        // these, like @AbstractBindingMethod
-        Binds.class,
-        Multibinds.class,
-        BindsOptionalOf.class);
-  }
-
-  /** The key for this requirement, if one is available. */
-  abstract Optional<Key> key();
-
-  /** Returns the name for this requirement that could be used as a variable. */
-  abstract String variableName();
-
-  /** Returns a parameter spec for this requirement. */
-  ParameterSpec toParameterSpec() {
-    return ParameterSpec.builder(TypeName.get(type()), variableName()).build();
-  }
-
-  /** Creates a proto representation of this requirement. */
-  ComponentRequirementProto toProto() {
-    switch (kind()) {
-      case DEPENDENCY:
-        return ComponentRequirementProto.newBuilder()
-            .setDependency(TypeProtoConverter.toProto(type()))
-            .build();
-      case MODULE:
-        return ComponentRequirementProto.newBuilder()
-            .setModule(TypeProtoConverter.toProto(type()))
-            .build();
-      case BOUND_INSTANCE:
-        return ComponentRequirementProto.newBuilder()
-            .setBoundInstance(
-                BoundInstanceRequirement.newBuilder()
-                    .setKey(KeyFactory.toProto(key().get()))
-                    .setNullable(overrideNullPolicy().equals(Optional.of(NullPolicy.ALLOW)))
-                    .setVariableName(variableName()))
-            .build();
-    }
-    throw new AssertionError(this);
-  }
-
-  static ComponentRequirement forDependency(TypeMirror type) {
-    return new AutoValue_ComponentRequirement(
-        Kind.DEPENDENCY,
-        MoreTypes.equivalence().wrap(checkNotNull(type)),
-        Optional.empty(),
-        Optional.empty(),
-        simpleVariableName(MoreTypes.asTypeElement(type)));
-  }
-
-  static ComponentRequirement forModule(TypeMirror type) {
-    return new AutoValue_ComponentRequirement(
-        Kind.MODULE,
-        MoreTypes.equivalence().wrap(checkNotNull(type)),
-        Optional.empty(),
-        Optional.empty(),
-        simpleVariableName(MoreTypes.asTypeElement(type)));
-  }
-
-  static ComponentRequirement forBoundInstance(Key key, boolean nullable, String variableName) {
-    return new AutoValue_ComponentRequirement(
-        Kind.BOUND_INSTANCE,
-        MoreTypes.equivalence().wrap(key.type()),
-        nullable ? Optional.of(NullPolicy.ALLOW) : Optional.empty(),
-        Optional.of(key),
-        variableName);
-  }
-
-  static ComponentRequirement forBoundInstance(ContributionBinding binding) {
-    checkArgument(binding.kind().equals(BindingKind.BOUND_INSTANCE));
-    return forBoundInstance(
-        binding.key(),
-        binding.nullableType().isPresent(),
-        binding.bindingElement().get().getSimpleName().toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java b/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java
deleted file mode 100644
index d6aa053..0000000
--- a/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.javapoet.Expression;
-
-/**
- * A binding expression for instances bound with {@link dagger.BindsInstance} and instances of
- * {@linkplain dagger.Component#dependencies() component} and {@linkplain
- * dagger.producers.ProductionComponent#dependencies() production component dependencies}.
- */
-final class ComponentRequirementBindingExpression extends SimpleInvocationBindingExpression {
-  private final ComponentRequirement componentRequirement;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-
-  ComponentRequirementBindingExpression(
-      ResolvedBindings resolvedBindings,
-      ComponentRequirement componentRequirement,
-      ComponentRequirementExpressions componentRequirementExpressions) {
-    super(resolvedBindings);
-    this.componentRequirement = componentRequirement;
-    this.componentRequirementExpressions = componentRequirementExpressions;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    return Expression.create(
-        componentRequirement.type(),
-        componentRequirementExpressions.getExpression(componentRequirement, requestingClass));
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentRequirementExpression.java b/java/dagger/internal/codegen/ComponentRequirementExpression.java
deleted file mode 100644
index b25c01b..0000000
--- a/java/dagger/internal/codegen/ComponentRequirementExpression.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-
-/**
- * A factory for expressions of {@link ComponentRequirement}s in the generated component. This is
- * <em>not</em> a {@link BindingExpression}, since {@link ComponentRequirement}s do not have a
- * {@link dagger.model.Key}. See {@link ComponentRequirementBindingExpression} for binding
- * expressions that are themselves a component requirement.
- */
-interface ComponentRequirementExpression {
-  /**
-   * Returns an expression for the {@link ComponentRequirement} to be used when implementing a
-   * component method. This may add a field or method to the component in order to reference the
-   * component requirement outside of the {@code initialize()} methods.
-   */
-  CodeBlock getExpression(ClassName requestingClass);
-
-  /**
-   * Returns an expression for the {@link ComponentRequirement} to be used only within {@code
-   * initialize()} methods, where the constructor parameters are available.
-   *
-   * <p>When accessing this expression from a subcomponent, this may cause a field to be initialized
-   * or a method to be added in the component that owns this {@link ComponentRequirement}.
-   */
-  default CodeBlock getExpressionDuringInitialization(ClassName requestingClass) {
-    return getExpression(requestingClass);
-  }
-
-  /**
-   * Returns the expression for the {@link ComponentRequirement} to be used when reimplementing a
-   * modifiable module method.
-   */
-  default CodeBlock getModifiableModuleMethodExpression(ClassName requestingClass) {
-    return CodeBlock.of("return $L", getExpression(requestingClass));
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentRequirementExpressions.java b/java/dagger/internal/codegen/ComponentRequirementExpressions.java
deleted file mode 100644
index 4ab58c9..0000000
--- a/java/dagger/internal/codegen/ComponentRequirementExpressions.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (C) 2017 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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Suppliers.memoize;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.ComponentImplementation.FieldSpecKind.COMPONENT_REQUIREMENT_FIELD;
-import static dagger.internal.codegen.ModuleProxies.newModuleInstance;
-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.PROTECTED;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A central repository of expressions used to access any {@link ComponentRequirement} available to
- * a component.
- */
-@PerComponentImplementation
-final class ComponentRequirementExpressions {
-
-  // TODO(dpb,ronshapiro): refactor this and ComponentBindingExpressions into a
-  // HierarchicalComponentMap<K, V>, or perhaps this use a flattened ImmutableMap, built from its
-  // parents? If so, maybe make ComponentRequirementExpression.Factory create it.
-
-  private final Optional<ComponentRequirementExpressions> parent;
-  private final Map<ComponentRequirement, ComponentRequirementExpression>
-      componentRequirementExpressions = new HashMap<>();
-  private final BindingGraph graph;
-  private final ComponentImplementation componentImplementation;
-  private final CompilerOptions compilerOptions;
-  private final DaggerElements elements;
-
-  // TODO(ronshapiro): give ComponentImplementation a graph() method
-  @Inject
-  ComponentRequirementExpressions(
-      @ParentComponent Optional<ComponentRequirementExpressions> parent,
-      BindingGraph graph,
-      ComponentImplementation componentImplementation,
-      CompilerOptions compilerOptions,
-      DaggerElements elements) {
-    this.parent = parent;
-    this.graph = graph;
-    this.componentImplementation = componentImplementation;
-    this.compilerOptions = compilerOptions;
-    this.elements = elements;
-  }
-
-  /**
-   * Returns an expression for the {@code componentRequirement} to be used when implementing a
-   * component method. This may add a field or method to the component in order to reference the
-   * component requirement outside of the {@code initialize()} methods.
-   */
-  CodeBlock getExpression(ComponentRequirement componentRequirement, ClassName requestingClass) {
-    return getExpression(componentRequirement).getExpression(requestingClass);
-  }
-
-  /**
-   * Returns an expression for the {@code componentRequirement} to be used only within {@code
-   * initialize()} methods, where the component constructor parameters are available.
-   *
-   * <p>When accessing this expression from a subcomponent, this may cause a field to be initialized
-   * or a method to be added in the component that owns this {@link ComponentRequirement}.
-   */
-  CodeBlock getExpressionDuringInitialization(
-      ComponentRequirement componentRequirement, ClassName requestingClass) {
-    return getExpression(componentRequirement).getExpressionDuringInitialization(requestingClass);
-  }
-
-  ComponentRequirementExpression getExpression(ComponentRequirement componentRequirement) {
-    if (graph.componentRequirements().contains(componentRequirement)) {
-      return componentRequirementExpressions.computeIfAbsent(
-          componentRequirement, this::createMethodOrField);
-    }
-    if (parent.isPresent()) {
-      return parent.get().getExpression(componentRequirement);
-    }
-
-    if (componentRequirement.kind().isModule() && compilerOptions.aheadOfTimeSubcomponents()) {
-      return new PrunedModifiableModule(componentRequirement);
-    }
-
-    throw new IllegalStateException(
-        "no component requirement expression found for " + componentRequirement);
-  }
-
-  /**
-   * If {@code requirement} is a module that may be owned by a future ancestor component, returns a
-   * modifiable module method. Otherwise, returns a field for {@code requirement}.
-   */
-  private ComponentRequirementExpression createMethodOrField(ComponentRequirement requirement) {
-    if (componentImplementation.isAbstract() && requirement.kind().isModule()) {
-      return new ModifiableModule(requirement);
-    }
-    return createField(requirement);
-  }
-
-  /** Returns a field for a {@link ComponentRequirement}. */
-  private ComponentRequirementExpression createField(ComponentRequirement requirement) {
-    if (componentImplementation.componentDescriptor().hasCreator()) {
-      return new ComponentParameterField(requirement, componentImplementation, Optional.empty());
-    } else if (graph.factoryMethod().isPresent()
-        && graph.factoryMethodParameters().containsKey(requirement)) {
-      String parameterName =
-          graph.factoryMethodParameters().get(requirement).getSimpleName().toString();
-      return new ComponentParameterField(
-          requirement, componentImplementation, Optional.of(parameterName));
-    } else if (requirement.kind().isModule()) {
-      return new InstantiableModuleField(requirement, componentImplementation);
-    } else {
-      throw new AssertionError(
-          String.format("Can't create %s in %s", requirement, componentImplementation.name()));
-    }
-  }
-
-  private abstract static class AbstractField implements ComponentRequirementExpression {
-    final ComponentRequirement componentRequirement;
-    final ComponentImplementation componentImplementation;
-    final String fieldName;
-    private final Supplier<MemberSelect> field = memoize(this::addField);
-
-    private AbstractField(
-        ComponentRequirement componentRequirement,
-        ComponentImplementation componentImplementation) {
-      this.componentRequirement = checkNotNull(componentRequirement);
-      this.componentImplementation = checkNotNull(componentImplementation);
-      // Note: The field name is being claimed eagerly here even though we don't know at this point
-      // whether or not the requirement will even need a field. This is done because:
-      // A) ComponentParameterField wants to ensure that it doesn't give the parameter the same name
-      //    as any field in the component, which requires that it claim a "field name" for itself
-      //    when naming the parameter.
-      // B) The parameter name may be needed before the field name is.
-      // C) We want to prefer giving the best name to the field rather than the parameter given its
-      //    wider scope.
-      this.fieldName =
-          componentImplementation.getUniqueFieldName(componentRequirement.variableName());
-    }
-
-    @Override
-    public CodeBlock getExpression(ClassName requestingClass) {
-      return field.get().getExpressionFor(requestingClass);
-    }
-
-    private MemberSelect addField() {
-      FieldSpec field = createField();
-      componentImplementation.addField(COMPONENT_REQUIREMENT_FIELD, field);
-      componentImplementation.addComponentRequirementInitialization(fieldInitialization(field));
-      return MemberSelect.localField(componentImplementation.name(), fieldName);
-    }
-
-    private FieldSpec createField() {
-      FieldSpec.Builder field =
-          FieldSpec.builder(TypeName.get(componentRequirement.type()), fieldName, PRIVATE);
-      if (!componentImplementation.isAbstract()) {
-        field.addModifiers(FINAL);
-      }
-      return field.build();
-    }
-
-    /** Returns the {@link CodeBlock} that initializes the component field during construction. */
-    abstract CodeBlock fieldInitialization(FieldSpec componentField);
-  }
-
-  /**
-   * A {@link ComponentRequirementExpression} for {@link ComponentRequirement}s that can be
-   * instantiated by the component (i.e. a static class with a no-arg constructor).
-   */
-  private final class InstantiableModuleField extends AbstractField {
-    private final TypeElement moduleElement;
-
-    private InstantiableModuleField(
-        ComponentRequirement module, ComponentImplementation componentImplementation) {
-      super(module, componentImplementation);
-      checkArgument(module.kind().isModule());
-      this.moduleElement = module.typeElement();
-    }
-
-    @Override
-    CodeBlock fieldInitialization(FieldSpec componentField) {
-      return CodeBlock.of(
-          "this.$N = $L;",
-          componentField,
-          newModuleInstance(moduleElement, componentImplementation.name(), elements));
-    }
-  }
-
-  /**
-   * A {@link ComponentRequirementExpression} for {@link ComponentRequirement}s that are passed in
-   * as parameters to the component's constructor.
-   */
-  private static final class ComponentParameterField extends AbstractField {
-    private final String parameterName;
-
-    private ComponentParameterField(
-        ComponentRequirement componentRequirement,
-        ComponentImplementation componentImplementation,
-        Optional<String> name) {
-      super(componentRequirement, componentImplementation);
-      componentImplementation.addComponentRequirementParameter(componentRequirement);
-      // Get the name that the component implementation will use for its parameter for the
-      // requirement. If the given name is different than the name of the field created for the
-      // requirement (as may be the case when the parameter name is derived from a user-written
-      // factory method parameter), just use that as the base name for the parameter. Otherwise,
-      // append "Param" to the end of the name to differentiate.
-      // In either case, componentImplementation.getParameterName() will ensure that the final name
-      // that is used is not the same name as any field in the component even if there's something
-      // weird where the component actually has fields named, say, "foo" and "fooParam".
-      String baseName = name.filter(n -> !n.equals(fieldName)).orElse(fieldName + "Param");
-      this.parameterName = componentImplementation.getParameterName(componentRequirement, baseName);
-    }
-
-    @Override
-    public CodeBlock getExpressionDuringInitialization(ClassName requestingClass) {
-      if (componentImplementation.name().equals(requestingClass)) {
-        return CodeBlock.of("$L", parameterName);
-      } else {
-        // requesting this component requirement during initialization of a child component requires
-        // it to be accessed from a field and not the parameter (since it is no longer available)
-        return getExpression(requestingClass);
-      }
-    }
-
-    @Override
-    CodeBlock fieldInitialization(FieldSpec componentField) {
-      // Don't checkNotNull here because the parameter may be nullable; if it isn't, the caller
-      // should handle checking that before passing the parameter.
-      return CodeBlock.of("this.$N = $L;", componentField, parameterName);
-    }
-  }
-
-  private final class ModifiableModule implements ComponentRequirementExpression {
-    private final ComponentRequirement module;
-    private final Supplier<MemberSelect> method = Suppliers.memoize(this::methodSelect);
-
-    private ModifiableModule(ComponentRequirement module) {
-      checkArgument(module.kind().isModule());
-      this.module = module;
-    }
-
-    @Override
-    public CodeBlock getExpression(ClassName requestingClass) {
-      return method.get().getExpressionFor(requestingClass);
-    }
-
-    private MemberSelect methodSelect() {
-      String methodName =
-          componentImplementation
-              .supertypeModifiableModuleMethodName(module)
-              .orElseGet(this::createMethod);
-      return MemberSelect.localMethod(componentImplementation.name(), methodName);
-    }
-
-    private String createMethod() {
-      String methodName =
-          UPPER_CAMEL.to(
-              LOWER_CAMEL,
-              componentImplementation.getUniqueMethodName(
-                  module.typeElement().getSimpleName().toString()));
-      MethodSpec.Builder methodBuilder =
-          methodBuilder(methodName)
-              .addModifiers(PROTECTED)
-              .returns(TypeName.get(module.type()));
-      // TODO(b/117833324): if the module is instantiable, we could provide an implementation here
-      // too. Then, if no ancestor ever repeats the module, there's nothing to do in subclasses.
-      if (graph.componentDescriptor().creatorDescriptor().isPresent()) {
-        methodBuilder.addStatement(
-            "return $L",
-            createField(module).getExpression(componentImplementation.name()));
-      } else {
-        methodBuilder.addModifiers(ABSTRACT);
-      }
-      componentImplementation.addModifiableModuleMethod(module, methodBuilder.build());
-      return methodName;
-    }
-  }
-
-  private static final class PrunedModifiableModule implements ComponentRequirementExpression {
-    private final ComponentRequirement module;
-
-    private PrunedModifiableModule(ComponentRequirement module) {
-      checkArgument(module.kind().isModule());
-      this.module = module;
-    }
-
-    @Override
-    public CodeBlock getExpression(ClassName requestingClass) {
-      throw new UnsupportedOperationException(module + " is pruned - it cannot be requested");
-    }
-
-    @Override
-    public CodeBlock getModifiableModuleMethodExpression(ClassName requestingClass) {
-      return CodeBlock.builder()
-          .add(
-              "// $L has been pruned from the final resolved binding graph. The result of this "
-                  + "method should never be used, but it may be called in an initialize() method "
-                  + "when creating a framework instance of a now-pruned binding. Those framework "
-                  + "instances should never be used.\n",
-              module.typeElement())
-          .add("return null")
-          .build();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentTreeTraverser.java b/java/dagger/internal/codegen/ComponentTreeTraverser.java
deleted file mode 100644
index cc1efd2..0000000
--- a/java/dagger/internal/codegen/ComponentTreeTraverser.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 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.checkState;
-import static com.google.common.base.Verify.verify;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterators;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.model.ComponentPath;
-import dagger.model.DependencyRequest;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * An object that traverses the entire component hierarchy, starting from the root component.
- *
- * <p>Subclasses can override {@link #visitComponent(BindingGraph)} to perform custom logic at each
- * component in the tree, and {@link #visitSubcomponentFactoryMethod(BindingGraph, BindingGraph,
- * ExecutableElement)} to perform custom logic at each subcomponent factory method.
- */
-public class ComponentTreeTraverser {
-
-  /** The path from the root graph to the currently visited graph. */
-  private final Deque<BindingGraph> bindingGraphPath = new ArrayDeque<>();
-
-  /** The {@link ComponentPath} for each component in {@link #bindingGraphPath}. */
-  private final Deque<ComponentPath> componentPaths = new ArrayDeque<>();
-
-  /** Constructs a traverser for a root (component, not subcomponent) binding graph. */
-  public ComponentTreeTraverser(BindingGraph rootGraph) {
-    bindingGraphPath.add(rootGraph);
-    componentPaths.add(ComponentPath.create(ImmutableList.of(rootGraph.componentTypeElement())));
-  }
-
-  /**
-   * Calls {@link #visitComponent(BindingGraph)} for the root component.
-   *
-   * @throws IllegalStateException if a traversal is in progress
-   */
-  public final void traverseComponents() {
-    checkState(bindingGraphPath.size() == 1);
-    checkState(componentPaths.size() == 1);
-    visitComponent(bindingGraphPath.getFirst());
-  }
-
-  /**
-   * Called once for each component in a component hierarchy.
-   *
-   * <p>Subclasses can override this method to perform whatever logic is required per component.
-   * They should call the {@code super} implementation if they want to continue the traversal in the
-   * standard order.
-   *
-   * <p>This implementation does the following:
-   *
-   * <ol>
-   *   <li>If this component is installed in its parent by a subcomponent factory method, calls
-   *       {@link #visitSubcomponentFactoryMethod(BindingGraph, BindingGraph, ExecutableElement)}.
-   *   <li>For each entry point in the component, calls {@link #visitEntryPoint(DependencyRequest,
-   *       BindingGraph)}.
-   *   <li>For each child component, calls {@link #visitComponent(BindingGraph)}, updating the
-   *       traversal state.
-   * </ol>
-   *
-   * @param graph the currently visited graph
-   */
-  protected void visitComponent(BindingGraph graph) {
-    if (bindingGraphPath.size() > 1) {
-      BindingGraph parent = Iterators.get(bindingGraphPath.descendingIterator(), 1);
-      parent
-          .componentDescriptor()
-          .getFactoryMethodForChildComponent(graph.componentDescriptor())
-          .ifPresent(
-              childFactoryMethod ->
-                  visitSubcomponentFactoryMethod(
-                      graph, parent, childFactoryMethod.methodElement()));
-    }
-
-    for (ComponentMethodDescriptor entryPointMethod :
-        graph.componentDescriptor().entryPointMethods()) {
-      visitEntryPoint(entryPointMethod.dependencyRequest().get(), graph);
-    }
-
-    for (BindingGraph child : graph.subgraphs()) {
-      bindingGraphPath.addLast(child);
-      ComponentPath childPath =
-          ComponentPath.create(
-              bindingGraphPath.stream()
-                  .map(BindingGraph::componentTypeElement)
-                  .collect(toImmutableList()));
-      componentPaths.addLast(childPath);
-      try {
-        visitComponent(child);
-      } finally {
-        verify(bindingGraphPath.removeLast().equals(child));
-        verify(componentPaths.removeLast().equals(childPath));
-      }
-    }
-  }
-
-  /**
-   * Called if this component was installed in its parent by a subcomponent factory method.
-   *
-   * <p>This implementation does nothing.
-   *
-   * @param graph the currently visited graph
-   * @param parent the parent graph
-   * @param factoryMethod the factory method in the parent component that declares that the current
-   *     component is a child
-   */
-  protected void visitSubcomponentFactoryMethod(
-      BindingGraph graph, BindingGraph parent, ExecutableElement factoryMethod) {}
-
-  /**
-   * Called once for each entry point in a component.
-   *
-   * <p>Subclasses can override this method to perform whatever logic is required per entry point.
-   * They should call the {@code super} implementation if they want to continue the traversal in the
-   * standard order.
-   *
-   * <p>This implementation does nothing.
-   *
-   * @param graph the graph for the component that contains the entry point
-   */
-  protected void visitEntryPoint(DependencyRequest entryPoint, BindingGraph graph) {}
-
-  /**
-   * Returns an immutable snapshot of the path from the root component to the currently visited
-   * component.
-   */
-  protected final ComponentPath componentPath() {
-    return componentPaths.getLast();
-  }
-
-  /**
-   * Returns the subpath from the root component to the matching {@code ancestor} of the current
-   * component.
-   */
-  protected final ComponentPath pathFromRootToAncestor(TypeElement ancestor) {
-    for (ComponentPath componentPath : componentPaths) {
-      if (componentPath.currentComponent().equals(ancestor)) {
-        return componentPath;
-      }
-    }
-    throw new IllegalArgumentException(
-        String.format("%s is not in the current path: %s", ancestor.getQualifiedName(), this));
-  }
-
-  /**
-   * Returns the BindingGraph for {@code ancestor}, where {@code ancestor} is in the component path
-   * of the current traversal.
-   */
-  protected final BindingGraph graphForAncestor(TypeElement ancestor) {
-    for (BindingGraph graph : bindingGraphPath) {
-      if (graph.componentTypeElement().equals(ancestor)) {
-        return graph;
-      }
-    }
-    throw new IllegalArgumentException(
-        String.format("%s is not in the current path: %s", ancestor.getQualifiedName(), this));
-  }
-}
diff --git a/java/dagger/internal/codegen/ComponentValidator.java b/java/dagger/internal/codegen/ComponentValidator.java
deleted file mode 100644
index 7739915..0000000
--- a/java/dagger/internal/codegen/ComponentValidator.java
+++ /dev/null
@@ -1,522 +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.auto.common.MoreElements.asType;
-import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.auto.common.MoreTypes.asDeclared;
-import static com.google.auto.common.MoreTypes.asExecutable;
-import static com.google.common.base.Verify.verify;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.common.collect.Multimaps.asMap;
-import static com.google.common.collect.Sets.intersection;
-import static dagger.internal.codegen.ComponentAnnotation.anyComponentAnnotation;
-import static dagger.internal.codegen.ComponentAnnotation.componentAnnotation;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.creatorAnnotationsFor;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.productionCreatorAnnotations;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.subcomponentCreatorAnnotations;
-import static dagger.internal.codegen.ComponentKind.annotationsFor;
-import static dagger.internal.codegen.ConfigurationAnnotations.enclosedAnnotatedTypes;
-import static dagger.internal.codegen.ConfigurationAnnotations.getTransitiveModules;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ErrorMessages.ComponentCreatorMessages.builderMethodRequiresNoArgs;
-import static dagger.internal.codegen.ErrorMessages.ComponentCreatorMessages.moreThanOneRefToSubcomponent;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnnotationMirror;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnyAnnotation;
-import static java.util.Comparator.comparing;
-import static javax.lang.model.element.ElementKind.CLASS;
-import static javax.lang.model.element.ElementKind.INTERFACE;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.type.TypeKind.VOID;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import dagger.Component;
-import dagger.Reusable;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.producers.CancellationPolicy;
-import dagger.producers.ProductionComponent;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.util.SimpleTypeVisitor6;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * Performs superficial validation of the contract of the {@link Component} and {@link
- * ProductionComponent} annotations.
- */
-final class ComponentValidator {
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final ModuleValidator moduleValidator;
-  private final ComponentCreatorValidator creatorValidator;
-  private final DependencyRequestValidator dependencyRequestValidator;
-  private final MembersInjectionValidator membersInjectionValidator;
-  private final MethodSignatureFormatter methodSignatureFormatter;
-  private final DependencyRequestFactory dependencyRequestFactory;
-
-  @Inject
-  ComponentValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      ModuleValidator moduleValidator,
-      ComponentCreatorValidator creatorValidator,
-      DependencyRequestValidator dependencyRequestValidator,
-      MembersInjectionValidator membersInjectionValidator,
-      MethodSignatureFormatter methodSignatureFormatter,
-      DependencyRequestFactory dependencyRequestFactory) {
-    this.elements = elements;
-    this.types = types;
-    this.moduleValidator = moduleValidator;
-    this.creatorValidator = creatorValidator;
-    this.dependencyRequestValidator = dependencyRequestValidator;
-    this.membersInjectionValidator = membersInjectionValidator;
-    this.methodSignatureFormatter = methodSignatureFormatter;
-    this.dependencyRequestFactory = dependencyRequestFactory;
-  }
-
-  @AutoValue
-  abstract static class ComponentValidationReport {
-    abstract ImmutableSet<Element> referencedSubcomponents();
-
-    abstract ValidationReport<TypeElement> report();
-  }
-
-  /**
-   * Validates the given component subject. Also validates any referenced subcomponents that aren't
-   * already included in the {@code validatedSubcomponents} set.
-   */
-  public ComponentValidationReport validate(
-      TypeElement subject,
-      Set<? extends Element> validatedSubcomponents,
-      Set<? extends Element> validatedSubcomponentCreators) {
-    ValidationReport.Builder<TypeElement> report = ValidationReport.about(subject);
-
-    ImmutableSet<ComponentKind> componentKinds = ComponentKind.getComponentKinds(subject);
-    ImmutableSet<Element> allSubcomponents;
-    if (componentKinds.size() > 1) {
-      String error =
-          "Components may not be annotated with more than one component annotation: found "
-              + annotationsFor(componentKinds);
-      report.addError(error, subject);
-      allSubcomponents = ImmutableSet.of();
-    } else {
-      ComponentKind componentKind = getOnlyElement(componentKinds);
-      ComponentAnnotation componentAnnotation = anyComponentAnnotation(subject).get();
-      allSubcomponents =
-          validate(
-              subject,
-              componentAnnotation,
-              componentKind,
-              validatedSubcomponents,
-              validatedSubcomponentCreators,
-              report);
-    }
-
-    return new AutoValue_ComponentValidator_ComponentValidationReport(
-        allSubcomponents, report.build());
-  }
-
-  private ImmutableSet<Element> validate(
-      TypeElement subject,
-      ComponentAnnotation componentAnnotation,
-      ComponentKind componentKind,
-      Set<? extends Element> validatedSubcomponents,
-      Set<? extends Element> validatedSubcomponentCreators,
-      ValidationReport.Builder<TypeElement> report) {
-    if (isAnnotationPresent(subject, CancellationPolicy.class) && !componentKind.isProducer()) {
-      report.addError(
-          "@CancellationPolicy may only be applied to production components and subcomponents",
-          subject);
-    }
-
-    if (!subject.getKind().equals(INTERFACE)
-        && !(subject.getKind().equals(CLASS) && subject.getModifiers().contains(ABSTRACT))) {
-      report.addError(
-          String.format(
-              "@%s may only be applied to an interface or abstract class",
-              componentKind.annotation().getSimpleName()),
-          subject);
-    }
-
-    ImmutableList<DeclaredType> creators =
-        creatorAnnotationsFor(componentAnnotation).stream()
-            .flatMap(annotation -> enclosedAnnotatedTypes(subject, annotation).stream())
-            .collect(toImmutableList());
-    if (creators.size() > 1) {
-      report.addError(
-          String.format(ErrorMessages.componentMessagesFor(componentKind).moreThanOne(), creators),
-          subject);
-    }
-
-    Optional<AnnotationMirror> reusableAnnotation = getAnnotationMirror(subject, Reusable.class);
-    if (reusableAnnotation.isPresent()) {
-      report.addError(
-          "@Reusable cannot be applied to components or subcomponents",
-          subject,
-          reusableAnnotation.get());
-    }
-
-    DeclaredType subjectType = MoreTypes.asDeclared(subject.asType());
-
-    SetMultimap<Element, ExecutableElement> referencedSubcomponents = LinkedHashMultimap.create();
-    getLocalAndInheritedMethods(subject, types, elements).stream()
-        .filter(method -> method.getModifiers().contains(ABSTRACT))
-        .forEachOrdered(
-            method -> {
-              ExecutableType resolvedMethod = asExecutable(types.asMemberOf(subjectType, method));
-              List<? extends TypeMirror> parameterTypes = resolvedMethod.getParameterTypes();
-              List<? extends VariableElement> parameters = method.getParameters();
-              TypeMirror returnType = resolvedMethod.getReturnType();
-
-              if (!resolvedMethod.getTypeVariables().isEmpty()) {
-                report.addError("Component methods cannot have type variables", method);
-              }
-
-              // abstract methods are ones we have to implement, so they each need to be validated
-              // first, check the return type. if it's a subcomponent, validate that method as such.
-              Optional<AnnotationMirror> subcomponentAnnotation =
-                  checkForAnnotations(
-                      returnType,
-                      componentKind.legalSubcomponentKinds().stream()
-                          .map(ComponentKind::annotation)
-                          .collect(toImmutableSet()));
-              Optional<AnnotationMirror> subcomponentCreatorAnnotation =
-                  checkForAnnotations(
-                      returnType,
-                      componentAnnotation.isProduction()
-                          ? intersection(
-                              subcomponentCreatorAnnotations(), productionCreatorAnnotations())
-                          : subcomponentCreatorAnnotations());
-              if (subcomponentAnnotation.isPresent()) {
-                referencedSubcomponents.put(MoreTypes.asElement(returnType), method);
-                validateSubcomponentMethod(
-                    report,
-                    ComponentKind.forAnnotatedElement(MoreTypes.asTypeElement(returnType)).get(),
-                    method,
-                    parameters,
-                    parameterTypes,
-                    returnType,
-                    subcomponentAnnotation);
-              } else if (subcomponentCreatorAnnotation.isPresent()) {
-                referencedSubcomponents.put(
-                    MoreTypes.asElement(returnType).getEnclosingElement(), method);
-                validateSubcomponentCreatorMethod(
-                    report, method, parameters, returnType, validatedSubcomponentCreators);
-              } else {
-                // if it's not a subcomponent...
-                switch (parameters.size()) {
-                  case 0:
-                    // no parameters means that it is a provision method
-                    dependencyRequestValidator.validateDependencyRequest(
-                        report, method, returnType);
-                    break;
-                  case 1:
-                    // one parameter means that it's a members injection method
-                    TypeMirror parameterType = Iterables.getOnlyElement(parameterTypes);
-                    report.addSubreport(
-                        membersInjectionValidator.validateMembersInjectionMethod(
-                            method, parameterType));
-                    if (!(returnType.getKind().equals(VOID)
-                        || types.isSameType(returnType, parameterType))) {
-                      report.addError(
-                          "Members injection methods may only return the injected type or void.",
-                          method);
-                    }
-                    break;
-                  default:
-                    // this isn't any method that we know how to implement...
-                    report.addError(
-                        "This method isn't a valid provision method, members injection method or "
-                            + "subcomponent factory method. Dagger cannot implement this method",
-                        method);
-                    break;
-                }
-              }
-            });
-
-    checkConflictingEntryPoints(report);
-
-    Maps.filterValues(referencedSubcomponents.asMap(), methods -> methods.size() > 1)
-        .forEach(
-            (subcomponent, methods) ->
-                report.addError(
-                    String.format(moreThanOneRefToSubcomponent(), subcomponent, methods), subject));
-
-    validateComponentDependencies(report, componentAnnotation.dependencyTypes());
-    report.addSubreport(
-        moduleValidator.validateReferencedModules(
-            subject,
-            componentAnnotation.annotation(),
-            componentKind.legalModuleKinds(),
-            new HashSet<>()));
-
-    // Make sure we validate any subcomponents we're referencing, unless we know we validated
-    // them already in this pass.
-    // TODO(sameb): If subcomponents refer to each other and both aren't in
-    //              'validatedSubcomponents' (e.g, both aren't compiled in this pass),
-    //              then this can loop forever.
-    ImmutableSet.Builder<Element> allSubcomponents =
-        ImmutableSet.<Element>builder().addAll(referencedSubcomponents.keySet());
-    for (Element subcomponent :
-        Sets.difference(referencedSubcomponents.keySet(), validatedSubcomponents)) {
-      ComponentValidationReport subreport =
-          validate(asType(subcomponent), validatedSubcomponents, validatedSubcomponentCreators);
-      report.addItems(subreport.report().items());
-      allSubcomponents.addAll(subreport.referencedSubcomponents());
-    }
-    return allSubcomponents.build();
-  }
-
-  private void checkConflictingEntryPoints(ValidationReport.Builder<TypeElement> report) {
-    DeclaredType componentType = asDeclared(report.getSubject().asType());
-
-    // Collect entry point methods that are not overridden by others. If the "same" method is
-    // inherited from more than one supertype, each will be in the multimap.
-    SetMultimap<String, ExecutableElement> entryPointMethods = HashMultimap.create();
-
-    methodsIn(elements.getAllMembers(report.getSubject()))
-        .stream()
-        .filter(
-            method -> isEntryPoint(method, asExecutable(types.asMemberOf(componentType, method))))
-        .forEach(
-            method ->
-                addMethodUnlessOverridden(
-                    method, entryPointMethods.get(method.getSimpleName().toString())));
-
-    for (Set<ExecutableElement> methods : asMap(entryPointMethods).values()) {
-      if (distinctKeys(methods, report.getSubject()).size() > 1) {
-        reportConflictingEntryPoints(methods, report);
-      }
-    }
-  }
-
-  private boolean isEntryPoint(ExecutableElement method, ExecutableType methodType) {
-    return method.getModifiers().contains(ABSTRACT)
-        && method.getParameters().isEmpty()
-        && !methodType.getReturnType().getKind().equals(VOID)
-        && methodType.getTypeVariables().isEmpty();
-  }
-
-  private ImmutableSet<Key> distinctKeys(Set<ExecutableElement> methods, TypeElement component) {
-    return methods
-        .stream()
-        .map(method -> dependencyRequest(method, component))
-        .map(DependencyRequest::key)
-        .collect(toImmutableSet());
-  }
-
-  private DependencyRequest dependencyRequest(ExecutableElement method, TypeElement component) {
-    ExecutableType methodType =
-        asExecutable(types.asMemberOf(asDeclared(component.asType()), method));
-    return ComponentKind.forAnnotatedElement(component).get().isProducer()
-        ? dependencyRequestFactory.forComponentProductionMethod(method, methodType)
-        : dependencyRequestFactory.forComponentProvisionMethod(method, methodType);
-  }
-
-  private void addMethodUnlessOverridden(ExecutableElement method, Set<ExecutableElement> methods) {
-    if (methods.stream().noneMatch(existingMethod -> overridesAsDeclared(existingMethod, method))) {
-      methods.removeIf(existingMethod -> overridesAsDeclared(method, existingMethod));
-      methods.add(method);
-    }
-  }
-
-  /**
-   * Returns {@code true} if {@code overrider} overrides {@code overridden} considered from within
-   * the type that declares {@code overrider}.
-   */
-  // TODO(dpb): Does this break for ECJ?
-  private boolean overridesAsDeclared(ExecutableElement overridder, ExecutableElement overridden) {
-    return elements.overrides(overridder, overridden, asType(overridder.getEnclosingElement()));
-  }
-
-  private void reportConflictingEntryPoints(
-      Collection<ExecutableElement> methods, ValidationReport.Builder<TypeElement> report) {
-    verify(
-        methods.stream().map(ExecutableElement::getEnclosingElement).distinct().count()
-            == methods.size(),
-        "expected each method to be declared on a different type: %s",
-        methods);
-    StringBuilder message = new StringBuilder("conflicting entry point declarations:");
-    methodSignatureFormatter
-        .typedFormatter(asDeclared(report.getSubject().asType()))
-        .formatIndentedList(
-            message,
-            ImmutableList.sortedCopyOf(
-                comparing(
-                    method -> asType(method.getEnclosingElement()).getQualifiedName().toString()),
-                methods),
-            1);
-    report.addError(message.toString());
-  }
-
-  private void validateSubcomponentMethod(
-      final ValidationReport.Builder<TypeElement> report,
-      final ComponentKind subcomponentKind,
-      ExecutableElement method,
-      List<? extends VariableElement> parameters,
-      List<? extends TypeMirror> parameterTypes,
-      TypeMirror returnType,
-      Optional<AnnotationMirror> subcomponentAnnotation) {
-    ImmutableSet<TypeElement> moduleTypes =
-        componentAnnotation(subcomponentAnnotation.get()).modules();
-
-    // TODO(gak): This logic maybe/probably shouldn't live here as it requires us to traverse
-    // subcomponents and their modules separately from how it is done in ComponentDescriptor and
-    // ModuleDescriptor
-    @SuppressWarnings("deprecation")
-    ImmutableSet<TypeElement> transitiveModules =
-        getTransitiveModules(types, elements, moduleTypes);
-
-    Set<TypeElement> variableTypes = Sets.newHashSet();
-
-    for (int i = 0; i < parameterTypes.size(); i++) {
-      VariableElement parameter = parameters.get(i);
-      TypeMirror parameterType = parameterTypes.get(i);
-      Optional<TypeElement> moduleType =
-          parameterType.accept(
-              new SimpleTypeVisitor6<Optional<TypeElement>, Void>() {
-                @Override
-                protected Optional<TypeElement> defaultAction(TypeMirror e, Void p) {
-                  return Optional.empty();
-                }
-
-                @Override
-                public Optional<TypeElement> visitDeclared(DeclaredType t, Void p) {
-                  for (ModuleKind moduleKind : subcomponentKind.legalModuleKinds()) {
-                    if (isAnnotationPresent(t.asElement(), moduleKind.annotation())) {
-                      return Optional.of(MoreTypes.asTypeElement(t));
-                    }
-                  }
-                  return Optional.empty();
-                }
-              },
-              null);
-      if (moduleType.isPresent()) {
-        if (variableTypes.contains(moduleType.get())) {
-          report.addError(
-              String.format(
-                  "A module may only occur once an an argument in a Subcomponent factory "
-                      + "method, but %s was already passed.",
-                  moduleType.get().getQualifiedName()),
-              parameter);
-        }
-        if (!transitiveModules.contains(moduleType.get())) {
-          report.addError(
-              String.format(
-                  "%s is present as an argument to the %s factory method, but is not one of the"
-                      + " modules used to implement the subcomponent.",
-                  moduleType.get().getQualifiedName(),
-                  MoreTypes.asTypeElement(returnType).getQualifiedName()),
-              method);
-        }
-        variableTypes.add(moduleType.get());
-      } else {
-        report.addError(
-            String.format(
-                "Subcomponent factory methods may only accept modules, but %s is not.",
-                parameterType),
-            parameter);
-      }
-    }
-  }
-
-  private void validateSubcomponentCreatorMethod(
-      ValidationReport.Builder<TypeElement> report,
-      ExecutableElement method,
-      List<? extends VariableElement> parameters,
-      TypeMirror returnType,
-      Set<? extends Element> validatedSubcomponentCreators) {
-    if (!parameters.isEmpty()) {
-      report.addError(builderMethodRequiresNoArgs(), method);
-    }
-
-    // If we haven't already validated the subcomponent creator itself, validate it now.
-    TypeElement creatorElement = MoreTypes.asTypeElement(returnType);
-    if (!validatedSubcomponentCreators.contains(creatorElement)) {
-      // TODO(sameb): The creator validator right now assumes the element is being compiled
-      // in this pass, which isn't true here.  We should change error messages to spit out
-      // this method as the subject and add the original subject to the message output.
-      report.addItems(creatorValidator.validate(creatorElement).items());
-    }
-  }
-
-  private static <T extends Element> void validateComponentDependencies(
-      ValidationReport.Builder<T> report, Iterable<TypeMirror> types) {
-    for (TypeMirror type : types) {
-      type.accept(CHECK_DEPENDENCY_TYPES, report);
-    }
-  }
-
-  private static final TypeVisitor<Void, ValidationReport.Builder<?>> CHECK_DEPENDENCY_TYPES =
-      new SimpleTypeVisitor8<Void, ValidationReport.Builder<?>>() {
-        @Override
-        protected Void defaultAction(TypeMirror type, ValidationReport.Builder<?> report) {
-          report.addError(type + " is not a valid component dependency type");
-          return null;
-        }
-
-        @Override
-        public Void visitDeclared(DeclaredType type, ValidationReport.Builder<?> report) {
-          if (moduleAnnotation(MoreTypes.asTypeElement(type)).isPresent()) {
-            report.addError(type + " is a module, which cannot be a component dependency");
-          }
-          return null;
-        }
-      };
-
-  private static Optional<AnnotationMirror> checkForAnnotations(
-      TypeMirror type, final Set<? extends Class<? extends Annotation>> annotations) {
-    return type.accept(
-        new SimpleTypeVisitor6<Optional<AnnotationMirror>, Void>(Optional.empty()) {
-          @Override
-          public Optional<AnnotationMirror> visitDeclared(DeclaredType t, Void p) {
-            return getAnyAnnotation(t.asElement(), annotations);
-          }
-        },
-        null);
-  }
-}
diff --git a/java/dagger/internal/codegen/ConfigurationAnnotations.java b/java/dagger/internal/codegen/ConfigurationAnnotations.java
deleted file mode 100644
index a9bba29..0000000
--- a/java/dagger/internal/codegen/ConfigurationAnnotations.java
+++ /dev/null
@@ -1,157 +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.collect.Iterables.consumingIterable;
-import static dagger.internal.codegen.ComponentAnnotation.subcomponentAnnotation;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.subcomponentCreatorAnnotations;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-import static dagger.internal.codegen.MoreAnnotationMirrors.getTypeListValue;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-import static javax.lang.model.util.ElementFilter.typesIn;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import dagger.Component;
-import dagger.Module;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.lang.annotation.Annotation;
-import java.util.ArrayDeque;
-import java.util.List;
-import java.util.Optional;
-import java.util.Queue;
-import java.util.Set;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Utility methods related to dagger configuration annotations (e.g.: {@link Component}
- * and {@link Module}).
- */
-final class ConfigurationAnnotations {
-
-  static Optional<TypeElement> getSubcomponentCreator(TypeElement subcomponent) {
-    checkArgument(subcomponentAnnotation(subcomponent).isPresent());
-    for (TypeElement nestedType : typesIn(subcomponent.getEnclosedElements())) {
-      if (isSubcomponentCreator(nestedType)) {
-        return Optional.of(nestedType);
-      }
-    }
-    return Optional.empty();
-  }
-
-  static boolean isSubcomponentCreator(Element element) {
-    return isAnyAnnotationPresent(element, subcomponentCreatorAnnotations());
-  }
-
-  // Dagger 1 support.
-  static ImmutableList<TypeMirror> getModuleInjects(AnnotationMirror moduleAnnotation) {
-    checkNotNull(moduleAnnotation);
-    return getTypeListValue(moduleAnnotation, "injects");
-  }
-
-  /** Returns the first type that specifies this' nullability, or empty if none. */
-  static Optional<DeclaredType> getNullableType(Element element) {
-    List<? extends AnnotationMirror> mirrors = element.getAnnotationMirrors();
-    for (AnnotationMirror mirror : mirrors) {
-      if (mirror.getAnnotationType().asElement().getSimpleName().contentEquals("Nullable")) {
-        return Optional.of(mirror.getAnnotationType());
-      }
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * 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} is
-   * not annotated with {@link Module}, it is ignored.
-   *
-   * @deprecated Use {@link ComponentDescriptor#modules()}.
-   */
-  @Deprecated
-  static ImmutableSet<TypeElement> getTransitiveModules(
-      DaggerTypes types, DaggerElements elements, Iterable<TypeElement> seedModules) {
-    TypeMirror objectType = elements.getTypeElement(Object.class).asType();
-    Queue<TypeElement> moduleQueue = new ArrayDeque<>();
-    Iterables.addAll(moduleQueue, seedModules);
-    Set<TypeElement> moduleElements = Sets.newLinkedHashSet();
-    for (TypeElement moduleElement : consumingIterable(moduleQueue)) {
-      moduleAnnotation(moduleElement)
-          .ifPresent(
-              moduleAnnotation -> {
-                ImmutableSet.Builder<TypeElement> moduleDependenciesBuilder =
-                    ImmutableSet.builder();
-                moduleDependenciesBuilder.addAll(moduleAnnotation.includes());
-                // We don't recur on the parent class because we don't want the parent class as a
-                // root that the component depends on, and also because we want the dependencies
-                // rooted against this element, not the parent.
-                addIncludesFromSuperclasses(
-                    types, moduleElement, moduleDependenciesBuilder, objectType);
-                ImmutableSet<TypeElement> moduleDependencies = moduleDependenciesBuilder.build();
-                moduleElements.add(moduleElement);
-                for (TypeElement dependencyType : moduleDependencies) {
-                  if (!moduleElements.contains(dependencyType)) {
-                    moduleQueue.add(dependencyType);
-                  }
-                }
-              });
-    }
-    return ImmutableSet.copyOf(moduleElements);
-  }
-
-  /** Returns the enclosed types annotated with the given annotation. */
-  static ImmutableList<DeclaredType> enclosedAnnotatedTypes(
-      TypeElement typeElement, Class<? extends Annotation> annotation) {
-    final ImmutableList.Builder<DeclaredType> builders = ImmutableList.builder();
-    for (TypeElement element : typesIn(typeElement.getEnclosedElements())) {
-      if (MoreElements.isAnnotationPresent(element, annotation)) {
-        builders.add(MoreTypes.asDeclared(element.asType()));
-      }
-    }
-    return builders.build();
-  }
-
-  /** Traverses includes from superclasses and adds them into the builder. */
-  private static void addIncludesFromSuperclasses(
-      DaggerTypes types,
-      TypeElement element,
-      ImmutableSet.Builder<TypeElement> builder,
-      TypeMirror objectType) {
-    // Also add the superclass to the queue, in case any @Module definitions were on that.
-    TypeMirror superclass = element.getSuperclass();
-    while (!types.isSameType(objectType, superclass)
-        && superclass.getKind().equals(TypeKind.DECLARED)) {
-      element = MoreElements.asType(types.asElement(superclass));
-      moduleAnnotation(element)
-          .ifPresent(moduleAnnotation -> builder.addAll(moduleAnnotation.includes()));
-      superclass = element.getSuperclass();
-    }
-  }
-
-  private ConfigurationAnnotations() {}
-}
diff --git a/java/dagger/internal/codegen/ContributionBinding.java b/java/dagger/internal/codegen/ContributionBinding.java
deleted file mode 100644
index 0958bc8..0000000
--- a/java/dagger/internal/codegen/ContributionBinding.java
+++ /dev/null
@@ -1,209 +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.checkState;
-import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.CLASS_CONSTRUCTOR;
-import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.DELEGATE;
-import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.SINGLETON_INSTANCE;
-import static dagger.internal.codegen.MapKeys.unwrapValue;
-import static dagger.internal.codegen.MoreAnnotationMirrors.unwrapOptionalEquivalence;
-import static java.util.Arrays.asList;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.base.Equivalence;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.internal.codegen.ContributionType.HasContributionType;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * An abstract class for a value object representing the mechanism by which a {@link Key} can be
- * contributed to a dependency graph.
- */
-abstract class ContributionBinding extends Binding implements HasContributionType {
-
-  /** Returns the type that specifies this' nullability, absent if not nullable. */
-  abstract Optional<DeclaredType> nullableType();
-
-  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedMapKeyAnnotation();
-
-  final Optional<AnnotationMirror> mapKeyAnnotation() {
-    return unwrapOptionalEquivalence(wrappedMapKeyAnnotation());
-  }
-
-  /**
-   * If this is a map contribution, returns the key of its map entry.
-   *
-   * @throws IllegalStateException if {@link #mapKeyAnnotation()} returns an empty value.
-   */
-  final Object mapKey() {
-    checkState(mapKeyAnnotation().isPresent());
-    AnnotationMirror mapKeyAnnotation = mapKeyAnnotation().get();
-    return unwrapValue(mapKeyAnnotation).map(AnnotationValue::getValue).orElse(mapKeyAnnotation);
-  }
-
-  /** If {@link #bindingElement()} is a method that returns a primitive type, returns that type. */
-  final Optional<TypeMirror> contributedPrimitiveType() {
-    return bindingElement()
-        .filter(bindingElement -> bindingElement instanceof ExecutableElement)
-        .map(bindingElement -> MoreElements.asExecutable(bindingElement).getReturnType())
-        .filter(type -> type.getKind().isPrimitive());
-  }
-
-  @Override
-  public final boolean isNullable() {
-    return nullableType().isPresent();
-  }
-
-  /**
-   * The strategy for getting an instance of a factory for a {@link ContributionBinding}.
-   */
-  enum FactoryCreationStrategy {
-    /** The factory class is a single instance. */
-    SINGLETON_INSTANCE,
-    /** The factory must be created by calling the constructor. */
-    CLASS_CONSTRUCTOR,
-    /** The factory is simply delegated to another. */
-    DELEGATE,
-  }
-
-  /**
-   * Returns the {@link FactoryCreationStrategy} appropriate for a binding.
-   *
-   * <p>Delegate bindings use the {@link FactoryCreationStrategy#DELEGATE} strategy.
-   *
-   * <p>Bindings without dependencies that don't require a module instance use the {@link
-   * FactoryCreationStrategy#SINGLETON_INSTANCE} strategy.
-   *
-   * <p>All other bindings use the {@link FactoryCreationStrategy#CLASS_CONSTRUCTOR} strategy.
-   */
-  final FactoryCreationStrategy factoryCreationStrategy() {
-    switch (kind()) {
-      case DELEGATE:
-        return DELEGATE;
-      case PROVISION:
-        return dependencies().isEmpty() && !requiresModuleInstance()
-            ? SINGLETON_INSTANCE
-            : CLASS_CONSTRUCTOR;
-      case INJECTION:
-      case MULTIBOUND_SET:
-      case MULTIBOUND_MAP:
-        return dependencies().isEmpty() ? SINGLETON_INSTANCE : CLASS_CONSTRUCTOR;
-      default:
-        return CLASS_CONSTRUCTOR;
-    }
-  }
-
-  /**
-   * The {@link TypeMirror type} for the {@code Factory<T>} or {@code Producer<T>} which is created
-   * for this binding. Uses the binding's key, V in the case of {@code Map<K, FrameworkClass<V>>>},
-   * and E {@code Set<E>} for {@link dagger.multibindings.IntoSet @IntoSet} methods.
-   */
-  final TypeMirror contributedType() {
-    switch (contributionType()) {
-      case MAP:
-        return MapType.from(key()).unwrappedFrameworkValueType();
-      case SET:
-        return SetType.from(key()).elementType();
-      case SET_VALUES:
-      case UNIQUE:
-        return key().type();
-    }
-    throw new AssertionError();
-  }
-
-  final boolean isSyntheticMultibinding() {
-    switch (kind()) {
-      case MULTIBOUND_SET:
-      case MULTIBOUND_MAP:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  /** Whether the bound type has a generated implementation. */
-  final boolean requiresGeneratedInstance() {
-    switch (kind()) {
-      case COMPONENT:
-      case SUBCOMPONENT_CREATOR:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  /**
-   * Returns {@link BindingKind#MULTIBOUND_SET} or {@link
-   * BindingKind#MULTIBOUND_MAP} if the key is a set or map.
-   *
-   * @throws IllegalArgumentException if {@code key} is neither a set nor a map
-   */
-  static BindingKind bindingKindForMultibindingKey(Key key) {
-    if (SetType.isSet(key)) {
-      return BindingKind.MULTIBOUND_SET;
-    } else if (MapType.isMap(key)) {
-      return BindingKind.MULTIBOUND_MAP;
-    } else {
-      throw new IllegalArgumentException(String.format("key is not for a set or map: %s", key));
-    }
-  }
-
-  /**
-   * Base builder for {@link com.google.auto.value.AutoValue @AutoValue} subclasses of {@link
-   * ContributionBinding}.
-   */
-  @CanIgnoreReturnValue
-  abstract static class Builder<C extends ContributionBinding, B extends Builder<C, B>> {
-    abstract B dependencies(Iterable<DependencyRequest> dependencies);
-
-    B dependencies(DependencyRequest... dependencies) {
-      return dependencies(asList(dependencies));
-    }
-
-    abstract B unresolved(C unresolved);
-
-    abstract B contributionType(ContributionType contributionType);
-
-    abstract B bindingElement(Element bindingElement);
-
-    abstract B contributingModule(TypeElement contributingModule);
-
-    abstract B key(Key key);
-
-    abstract B nullableType(Optional<DeclaredType> nullableType);
-
-    abstract B wrappedMapKeyAnnotation(
-        Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedMapKeyAnnotation);
-
-    abstract B kind(BindingKind kind);
-
-    @CheckReturnValue
-    abstract C build();
-  }
-}
diff --git a/java/dagger/internal/codegen/ContributionType.java b/java/dagger/internal/codegen/ContributionType.java
deleted file mode 100644
index 66b5289..0000000
--- a/java/dagger/internal/codegen/ContributionType.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreElements.isAnnotationPresent;
-
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import javax.lang.model.element.Element;
-
-/** Whether a binding or declaration is for a unique contribution or a map or set multibinding. */
-enum ContributionType {
-  /** Represents map bindings. */
-  MAP,
-  /** Represents set bindings. */
-  SET,
-  /** Represents set values bindings. */
-  SET_VALUES,
-  /** Represents a valid non-collection binding. */
-  UNIQUE,
-  ;
-
-  /** An object that is associated with a {@link ContributionType}. */
-  interface HasContributionType {
-
-    /** The contribution type of this object. */
-    ContributionType contributionType();
-  }
-
-  /** {@code true} if this is for a multibinding. */
-  boolean isMultibinding() {
-    return !this.equals(UNIQUE);
-  }
-
-  /**
-   * The contribution type from a binding element's annotations. Presumes a well-formed binding
-   * element (at most one of @IntoSet, @IntoMap, @ElementsIntoSet and @Provides.type). {@link
-   * BindingMethodValidator} and {@link BindsInstanceProcessingStep} validate correctness on their
-   * own.
-   */
-  static ContributionType fromBindingElement(Element element) {
-    if (isAnnotationPresent(element, IntoMap.class)) {
-      return ContributionType.MAP;
-    } else if (isAnnotationPresent(element, IntoSet.class)) {
-      return ContributionType.SET;
-    } else if (isAnnotationPresent(element, ElementsIntoSet.class)) {
-      return ContributionType.SET_VALUES;
-    }
-    return ContributionType.UNIQUE;
-  }
-}
diff --git a/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java b/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java
deleted file mode 100644
index c78d60d..0000000
--- a/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.BindsInstance;
-import dagger.Subcomponent;
-import dagger.internal.codegen.ComponentImplementationBuilder.RootComponentImplementationBuilder;
-import dagger.internal.codegen.ComponentImplementationBuilder.SubcomponentImplementationBuilder;
-import java.util.Optional;
-
-/**
- * A subcomponent that injects all objects that are responsible for creating a single {@link
- * ComponentImplementation} instance. Each child {@link ComponentImplementation} will have its own
- * instance of {@link CurrentImplementationSubcomponent}.
- */
-@Subcomponent(modules = GenerationOptionsModule.class)
-@PerComponentImplementation
-interface CurrentImplementationSubcomponent {
-  RootComponentImplementationBuilder rootComponentBuilder();
-
-  SubcomponentImplementationBuilder subcomponentBuilder();
-
-  @Subcomponent.Builder
-  interface Builder {
-    @BindsInstance
-    Builder componentImplementation(ComponentImplementation componentImplementation);
-
-    @BindsInstance
-    Builder bindingGraph(BindingGraph bindingGraph);
-
-    @BindsInstance
-    Builder parentBuilder(@ParentComponent Optional<ComponentImplementationBuilder> parentBuilder);
-
-    @BindsInstance
-    Builder parentBindingExpressions(
-        @ParentComponent Optional<ComponentBindingExpressions> parentBindingExpressions);
-
-    @BindsInstance
-    Builder parentRequirementExpressions(
-        @ParentComponent Optional<ComponentRequirementExpressions> parentRequirementExpressions);
-
-    CurrentImplementationSubcomponent build();
-  }
-}
diff --git a/java/dagger/internal/codegen/DaggerGraphs.java b/java/dagger/internal/codegen/DaggerGraphs.java
deleted file mode 100644
index dda6c11..0000000
--- a/java/dagger/internal/codegen/DaggerGraphs.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Sets.difference;
-import static com.google.common.graph.Graphs.reachableNodes;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.graph.Graph;
-import com.google.common.graph.SuccessorsFunction;
-import java.util.ArrayDeque;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-
-/** Utility methods for {@link com.google.common.graph} types. */
-public final class DaggerGraphs {
-  /**
-   * Returns a shortest path from {@code nodeU} to {@code nodeV} in {@code graph} as a list of the
-   * nodes visited in sequence, including both {@code nodeU} and {@code nodeV}. (Note that there may
-   * be many possible shortest paths.)
-   *
-   * <p>If {@code nodeV} is not {@link
-   * com.google.common.graph.Graphs#reachableNodes(com.google.common.graph.Graph, Object) reachable}
-   * from {@code nodeU}, the list returned is empty.
-   *
-   * @throws IllegalArgumentException if {@code nodeU} or {@code nodeV} is not present in {@code
-   *     graph}
-   */
-  public static <N> ImmutableList<N> shortestPath(SuccessorsFunction<N> graph, N nodeU, N nodeV) {
-    if (nodeU.equals(nodeV)) {
-      return ImmutableList.of(nodeU);
-    }
-    Set<N> successors = ImmutableSet.copyOf(graph.successors(nodeU));
-    if (successors.contains(nodeV)) {
-      return ImmutableList.of(nodeU, nodeV);
-    }
-
-    Map<N, N> visitedNodeToPathPredecessor = new HashMap<>(); // encodes shortest path tree
-    for (N node : successors) {
-      visitedNodeToPathPredecessor.put(node, nodeU);
-    }
-    Queue<N> currentNodes = new ArrayDeque<N>(successors);
-    Queue<N> nextNodes = new ArrayDeque<N>();
-
-    // Perform a breadth-first traversal starting with the successors of nodeU.
-    while (!currentNodes.isEmpty()) {
-      while (!currentNodes.isEmpty()) {
-        N currentNode = currentNodes.remove();
-        for (N nextNode : graph.successors(currentNode)) {
-          if (visitedNodeToPathPredecessor.containsKey(nextNode)) {
-            continue; // we already have a shortest path to nextNode
-          }
-          visitedNodeToPathPredecessor.put(nextNode, currentNode);
-          if (nextNode.equals(nodeV)) {
-            ImmutableList.Builder<N> builder = ImmutableList.builder();
-            N node = nodeV;
-            builder.add(node);
-            while (!node.equals(nodeU)) {
-              node = visitedNodeToPathPredecessor.get(node);
-              builder.add(node);
-            }
-            return builder.build().reverse();
-          }
-          nextNodes.add(nextNode);
-        }
-      }
-      Queue<N> emptyQueue = currentNodes;
-      currentNodes = nextNodes;
-      nextNodes = emptyQueue; // reusing empty queue faster than allocating new one
-    }
-
-    return ImmutableList.of();
-  }
-
-  /** Returns the nodes in a graph that are not reachable from a node. */
-  public static <N> ImmutableSet<N> unreachableNodes(Graph<N> graph, N node) {
-    return ImmutableSet.copyOf(difference(graph.nodes(), reachableNodes(graph, node)));
-  }
-
-  private DaggerGraphs() {}
-}
diff --git a/java/dagger/internal/codegen/DaggerKythePlugin.java b/java/dagger/internal/codegen/DaggerKythePlugin.java
deleted file mode 100644
index 5a685ef..0000000
--- a/java/dagger/internal/codegen/DaggerKythePlugin.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-// This must be in the dagger.internal.codegen package since Dagger doesn't expose its APIs publicly
-// https://github.com/google/dagger/issues/773 could present an opportunity to put this somewhere in
-// the regular kythe/java tree.
-package dagger.internal.codegen;
-
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-
-import com.google.auto.service.AutoService;
-import com.google.common.collect.Iterables;
-import com.google.devtools.kythe.analyzers.base.EntrySet;
-import com.google.devtools.kythe.analyzers.base.FactEmitter;
-import com.google.devtools.kythe.analyzers.base.KytheEntrySets;
-import com.google.devtools.kythe.analyzers.java.Plugin;
-import com.google.devtools.kythe.proto.Storage.VName;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.util.Context;
-import dagger.BindsInstance;
-import dagger.Component;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.producers.ProductionComponent;
-import java.util.Optional;
-import java.util.logging.Logger;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.lang.model.element.Element;
-
-/**
- * A plugin which emits nodes and edges for <a href="https://github.com/google/dagger">Dagger</a>
- * specific code.
- */
-@AutoService(Plugin.class)
-public class DaggerKythePlugin extends Plugin.Scanner<Void, Void> {
-  // TODO(ronshapiro): use flogger
-  private static final Logger logger = Logger.getLogger(DaggerKythePlugin.class.getCanonicalName());
-  private FactEmitter emitter;
-  @Inject ComponentDescriptorFactory componentDescriptorFactory;
-  @Inject BindingGraphFactory bindingGraphFactory;
-
-  @Override
-  public Void visitClassDef(JCClassDecl tree, Void p) {
-    if (tree.sym != null
-        && isAnyAnnotationPresent(tree.sym, Component.class, ProductionComponent.class)) {
-      addNodesForGraph(
-          bindingGraphFactory.create(
-              componentDescriptorFactory.rootComponentDescriptor(tree.sym), false));
-    }
-    return super.visitClassDef(tree, p);
-  }
-
-  private void addNodesForGraph(BindingGraph graph) {
-    addDependencyEdges(graph);
-    addModuleEdges(graph);
-    addChildComponentEdges(graph);
-
-    graph.subgraphs().forEach(this::addNodesForGraph);
-  }
-
-  private void addDependencyEdges(BindingGraph graph) {
-    for (ResolvedBindings resolvedBinding : graph.resolvedBindings()) {
-      for (Binding binding : resolvedBinding.bindings()) {
-        for (DependencyRequest dependency : binding.explicitDependencies()) {
-          addEdgesForDependencyRequest(dependency, dependency.key(), graph);
-        }
-      }
-    }
-
-    for (ComponentDescriptor.ComponentMethodDescriptor componentMethod :
-        graph.componentDescriptor().componentMethods()) {
-      componentMethod
-          .dependencyRequest()
-          .ifPresent(request -> addEdgesForDependencyRequest(request, request.key(), graph));
-    }
-  }
-
-  /**
-   * Add {@code /inject/satisfiedby} edges from {@code dependency}'s {@link
-   * DependencyRequest#requestElement()} to any {@link BindingDeclaration#bindingElement() binding
-   * elements} that satisfy the request.
-   *
-   * <p>This collapses requests for synthetic bindings so that a request for a multibound key
-   * points to all of the contributions for the multibound object. It does so by recursively calling
-   * this method, with each dependency's key as the {@code targetKey}.
-   */
-  private void addEdgesForDependencyRequest(
-      DependencyRequest dependency, Key targetKey, BindingGraph graph) {
-    if (!dependency.requestElement().isPresent()) {
-      return;
-    }
-    BindingRequest request = bindingRequest(targetKey, dependency.kind());
-    ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-    for (Binding binding : resolvedBindings.bindings()) {
-      if (binding.bindingElement().isPresent()) {
-        addDependencyEdge(dependency, binding);
-      } else {
-        for (DependencyRequest subsequentDependency : binding.explicitDependencies()) {
-          addEdgesForDependencyRequest(dependency, subsequentDependency.key(), graph);
-        }
-      }
-    }
-    for (BindingDeclaration bindingDeclaration :
-        Iterables.concat(
-            resolvedBindings.multibindingDeclarations(),
-            resolvedBindings.optionalBindingDeclarations())) {
-      addDependencyEdge(dependency, bindingDeclaration);
-    }
-  }
-
-  private void addDependencyEdge(
-      DependencyRequest dependency, BindingDeclaration bindingDeclaration) {
-    Element requestElement = dependency.requestElement().get();
-    Element bindingElement = bindingDeclaration.bindingElement().get();
-    Optional<VName> requestElementNode = jvmNode(requestElement, "request element");
-    Optional<VName> bindingElementNode = jvmNode(bindingElement, "binding element");
-    emitEdge(requestElementNode, "/inject/satisfiedby", bindingElementNode);
-    // TODO(ronshapiro): emit facts about the component that satisfies the edge
-  }
-
-  private void addModuleEdges(BindingGraph graph) {
-    Optional<VName> componentNode = jvmNode(graph.componentTypeElement(), "component");
-    for (ModuleDescriptor module : graph.componentDescriptor().modules()) {
-      Optional<VName> moduleNode = jvmNode(module.moduleElement(), "module");
-      emitEdge(componentNode, "/inject/installsmodule", moduleNode);
-    }
-  }
-
-  private void addChildComponentEdges(BindingGraph graph) {
-    Optional<VName> componentNode = jvmNode(graph.componentTypeElement(), "component");
-    for (BindingGraph subgraph : graph.subgraphs()) {
-      Optional<VName> subcomponentNode =
-          jvmNode(subgraph.componentTypeElement(), "child component");
-      emitEdge(componentNode, "/inject/childcomponent", subcomponentNode);
-    }
-  }
-
-  private Optional<VName> jvmNode(Element element, String name) {
-    Optional<VName> jvmNode = kytheGraph.getJvmNode((Symbol) element).map(KytheNode::getVName);
-    if (!jvmNode.isPresent()) {
-      logger.warning(String.format("Missing JVM node for %s: %s", name, element));
-    }
-    return jvmNode;
-  }
-
-  private void emitEdge(Optional<VName> source, String edgeName, Optional<VName> target) {
-    source.ifPresent(
-        s -> target.ifPresent(t -> new EntrySet.Builder(s, edgeName, t).build().emit(emitter)));
-  }
-
-  @Override
-  public void run(
-      JCCompilationUnit compilationUnit, KytheEntrySets entrySets, KytheGraph kytheGraph) {
-    if (bindingGraphFactory == null) {
-      emitter = entrySets.getEmitter();
-      DaggerDaggerKythePlugin_PluginComponent.builder()
-          .context(kytheGraph.getJavaContext())
-          .build()
-          .inject(this);
-    }
-    super.run(compilationUnit, entrySets, kytheGraph);
-  }
-
-  @Singleton
-  @Component(modules = JavacPluginModule.class)
-  interface PluginComponent {
-    void inject(DaggerKythePlugin plugin);
-
-    @Component.Builder
-    interface Builder {
-      @BindsInstance
-      Builder context(Context context);
-
-      PluginComponent build();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DaggerStatistics.java b/java/dagger/internal/codegen/DaggerStatistics.java
deleted file mode 100644
index 790ec76..0000000
--- a/java/dagger/internal/codegen/DaggerStatistics.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import java.time.Duration;
-
-/** Statistics collected over the course of Dagger annotation processing. */
-@AutoValue
-abstract class DaggerStatistics {
-  /** Returns a new {@link Builder}. */
-  static Builder builder() {
-    return new AutoValue_DaggerStatistics.Builder();
-  }
-
-  /** Returns a new {@link RoundStatistics} builder. */
-  static RoundStatistics.Builder roundBuilder() {
-    return new AutoValue_DaggerStatistics_RoundStatistics.Builder();
-  }
-
-  /** Total time spent in Dagger annotation processing. */
-  abstract Duration totalProcessingTime();
-
-  /** List of statistics for processing rounds that the Dagger processor handled. */
-  abstract ImmutableList<RoundStatistics> rounds();
-
-  /** Builder for {@link DaggerStatistics}. */
-  @AutoValue.Builder
-  abstract static class Builder {
-    /** Sets the given duration for the total time spent in Dagger processing. */
-    @CanIgnoreReturnValue
-    abstract Builder setTotalProcessingTime(Duration totalProcessingTime);
-
-    /** Returns a builder for adding processing round statistics. */
-    abstract ImmutableList.Builder<RoundStatistics> roundsBuilder();
-
-    /** Adds the given {@code round} statistics. */
-    @CanIgnoreReturnValue
-    final Builder addRound(RoundStatistics round) {
-      roundsBuilder().add(round);
-      return this;
-    }
-
-    /** Creates a new {@link DaggerStatistics} instance. */
-    abstract DaggerStatistics build();
-  }
-
-  /** Statistics for each processing step in a single processing round. */
-  @AutoValue
-  abstract static class RoundStatistics {
-    /** Map of processing step class to duration of that step for this round. */
-    abstract ImmutableMap<Class<? extends ProcessingStep>, Duration> stepDurations();
-
-    /** Builder for {@link RoundStatistics}. */
-    @AutoValue.Builder
-    abstract static class Builder {
-      /** Returns a builder for adding durations for each processing step for the round. */
-      abstract ImmutableMap.Builder<Class<? extends ProcessingStep>, Duration>
-          stepDurationsBuilder();
-
-      /** Adds the given {@code duration} for the given {@code step}. */
-      @CanIgnoreReturnValue
-      final Builder addStepDuration(ProcessingStep step, Duration duration) {
-        stepDurationsBuilder().put(step.getClass(), duration);
-        return this;
-      }
-
-      /** Creates a new {@link RoundStatistics} instance. */
-      abstract RoundStatistics build();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DaggerStatisticsCollectingProcessingStep.java b/java/dagger/internal/codegen/DaggerStatisticsCollectingProcessingStep.java
deleted file mode 100644
index 51f6fc3..0000000
--- a/java/dagger/internal/codegen/DaggerStatisticsCollectingProcessingStep.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 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.checkNotNull;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.common.collect.SetMultimap;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.lang.model.element.Element;
-
-/**
- * {@link ProcessingStep} that delegates to another {@code ProcessingStep} and collects timing
- * statistics for each processing round for that step.
- */
-final class DaggerStatisticsCollectingProcessingStep implements ProcessingStep {
-
-  private final ProcessingStep delegate;
-  private final DaggerStatisticsCollector statisticsCollector;
-
-  DaggerStatisticsCollectingProcessingStep(
-      ProcessingStep delegate, DaggerStatisticsCollector statisticsCollector) {
-    this.delegate = checkNotNull(delegate);
-    this.statisticsCollector = checkNotNull(statisticsCollector);
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return delegate.annotations();
-  }
-
-  @Override
-  public Set<? extends Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    statisticsCollector.stepStarted(delegate);
-    try {
-      return delegate.process(elementsByAnnotation);
-    } finally {
-      statisticsCollector.stepFinished(delegate);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DaggerStatisticsCollector.java b/java/dagger/internal/codegen/DaggerStatisticsCollector.java
deleted file mode 100644
index e14fbb7..0000000
--- a/java/dagger/internal/codegen/DaggerStatisticsCollector.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkState;
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Ticker;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/** Collects {@link DaggerStatistics} over the course of Dagger annotation processing. */
-@Singleton // for state sharing
-final class DaggerStatisticsCollector {
-
-  private final Ticker ticker;
-  private final Stopwatch totalRuntimeStopwatch;
-  private final Map<ProcessingStep, Stopwatch> stepStopwatches = new HashMap<>();
-
-  private final DaggerStatistics.Builder statisticsBuilder = DaggerStatistics.builder();
-  private DaggerStatistics.RoundStatistics.Builder roundBuilder = DaggerStatistics.roundBuilder();
-
-  private final Optional<DaggerStatisticsRecorder> statisticsRecorder;
-
-  @Inject
-  DaggerStatisticsCollector(Ticker ticker, Optional<DaggerStatisticsRecorder> statisticsRecorder) {
-    this.ticker = ticker;
-    this.totalRuntimeStopwatch = Stopwatch.createUnstarted(ticker);
-    this.statisticsRecorder = statisticsRecorder;
-  }
-
-  /** Called when Dagger annotation processing starts. */
-  void processingStarted() {
-    checkState(!totalRuntimeStopwatch.isRunning());
-    totalRuntimeStopwatch.start();
-  }
-
-  /** Called when the given {@code step} starts processing for a round. */
-  void stepStarted(ProcessingStep step) {
-    Stopwatch stopwatch =
-        stepStopwatches.computeIfAbsent(step, unused -> Stopwatch.createUnstarted(ticker));
-    stopwatch.start();
-  }
-
-  /** Called when the given {@code step} finishes processing for a round. */
-  void stepFinished(ProcessingStep step) {
-    Stopwatch stopwatch = stepStopwatches.get(step);
-    roundBuilder.addStepDuration(step, elapsedTime(stopwatch));
-    stopwatch.reset();
-  }
-
-  /** Called when Dagger finishes a processing round. */
-  void roundFinished() {
-    statisticsBuilder.addRound(roundBuilder.build());
-    roundBuilder = DaggerStatistics.roundBuilder();
-  }
-
-  /** Called when Dagger annotation processing completes. */
-  void processingStopped() {
-    checkState(totalRuntimeStopwatch.isRunning());
-    totalRuntimeStopwatch.stop();
-    statisticsBuilder.setTotalProcessingTime(elapsedTime(totalRuntimeStopwatch));
-
-    statisticsRecorder.ifPresent(
-        recorder -> recorder.recordStatistics(statisticsBuilder.build()));
-  }
-
-  @SuppressWarnings("StopwatchNanosToDuration") // intentional
-  private Duration elapsedTime(Stopwatch stopwatch) {
-    // Using the java 7 method here as opposed to the Duration-returning version to avoid issues
-    // when other annotation processors rely on java 7's guava
-    return Duration.ofNanos(stopwatch.elapsed(NANOSECONDS));
-  }
-}
diff --git a/java/dagger/internal/codegen/DaggerStatisticsRecorder.java b/java/dagger/internal/codegen/DaggerStatisticsRecorder.java
deleted file mode 100644
index 66f41d1..0000000
--- a/java/dagger/internal/codegen/DaggerStatisticsRecorder.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-/** Records collected {@link DaggerStatistics}. */
-interface DaggerStatisticsRecorder {
-  /** Records the given {@code statistics}. */
-  void recordStatistics(DaggerStatistics statistics);
-}
diff --git a/java/dagger/internal/codegen/DaggerStreams.java b/java/dagger/internal/codegen/DaggerStreams.java
deleted file mode 100644
index 50d17a6..0000000
--- a/java/dagger/internal/codegen/DaggerStreams.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2013 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 java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.toList;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Maps;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-/** Utilities for streams. */
-public final class DaggerStreams {
-
-  /**
-   * Returns a {@link Collector} that accumulates the input elements into a new {@link
-   * ImmutableList}, in encounter order.
-   */
-  // TODO(b/68008628): Use ImmutableList.toImmutableList().
-  public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() {
-    return collectingAndThen(toList(), ImmutableList::copyOf);
-  }
-
-  /**
-   * Returns a {@link Collector} that accumulates the input elements into a new {@link
-   * ImmutableSet}, in encounter order.
-   */
-  // TODO(b/68008628): Use ImmutableSet.toImmutableSet().
-  public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() {
-    return collectingAndThen(toList(), ImmutableSet::copyOf);
-  }
-
-  /**
-   * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys
-   * and values are the result of applying the provided mapping functions to the input elements.
-   * Entries appear in the result {@code ImmutableMap} in encounter order.
-   */
-  // TODO(b/68008628): Use ImmutableMap.toImmutableMap().
-  public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
-      Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {
-    return Collectors.mapping(
-        value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),
-        Collector.of(
-            ImmutableMap::builder,
-            (ImmutableMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry),
-            (left, right) -> left.putAll(right.build()),
-            ImmutableMap.Builder::build));
-  }
-
-  /**
-   * Returns a {@link Collector} that accumulates elements into an {@code ImmutableSetMultimap}
-   * whose keys and values are the result of applying the provided mapping functions to the input
-   * elements. Entries appear in the result {@code ImmutableSetMultimap} in encounter order.
-   */
-  // TODO(b/68008628): Use ImmutableSetMultimap.toImmutableSetMultimap().
-  public static <T, K, V> Collector<T, ?, ImmutableSetMultimap<K, V>> toImmutableSetMultimap(
-      Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) {
-    return Collectors.mapping(
-        value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),
-        Collector.of(
-            ImmutableSetMultimap::builder,
-            (ImmutableSetMultimap.Builder<K, V> builder, Map.Entry<K, V> entry) ->
-                builder.put(entry),
-            (left, right) -> left.putAll(right.build()),
-            ImmutableSetMultimap.Builder::build));
-  }
-
-  /**
-   * Returns a function from {@link Object} to {@code Stream<T>}, which returns a stream containing
-   * its input if its input is an instance of {@code T}.
-   *
-   * <p>Use as an argument to {@link Stream#flatMap(Function)}:
-   *
-   * <pre>{@code Stream<Bar>} barStream = fooStream.flatMap(instancesOf(Bar.class));</pre>
-   */
-  public static <T> Function<Object, Stream<T>> instancesOf(Class<T> to) {
-    return f -> to.isInstance(f) ? Stream.of(to.cast(f)) : Stream.empty();
-  }
-
-  /** Returns a stream of all values of the given {@code enumType}. */
-  public static <E extends Enum<E>> Stream<E> valuesOf(Class<E> enumType) {
-    return EnumSet.allOf(enumType).stream();
-  }
-
-  /**
-   * A function that you can use to extract the present values from a stream of {@link Optional}s.
-   *
-   * <pre>{@code
-   * Set<Foo> foos =
-   *     optionalFoos()
-   *         .flatMap(DaggerStreams.presentValues())
-   *         .collect(toSet());
-   * }</pre>
-   */
-  public static <T> Function<Optional<T>, Stream<T>> presentValues() {
-    return optional -> optional.map(Stream::of).orElse(Stream.empty());
-  }
-
-  /**
-   * Returns a sequential {@link Stream} of the contents of {@code iterable}, delegating to {@link
-   * Collection#stream} if possible.
-   */
-  public static <T> Stream<T> stream(Iterable<T> iterable) {
-    return (iterable instanceof Collection)
-        ? ((Collection<T>) iterable).stream()
-        : StreamSupport.stream(iterable.spliterator(), false);
-  }
-
-  private DaggerStreams() {}
-}
diff --git a/java/dagger/internal/codegen/DeferredModifiableBindingExpression.java b/java/dagger/internal/codegen/DeferredModifiableBindingExpression.java
deleted file mode 100644
index c41cf2c..0000000
--- a/java/dagger/internal/codegen/DeferredModifiableBindingExpression.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A {@link ModifiableAbstractMethodBindingExpression} for a binding that exists but is not ready to
- * be expressed in this compilation unit and should be deferred until a future compilation.
- * Generates a method that will be implemented in the future compilation.
- *
- * <p>A deferred modifiable binding expression is used when:
- *
- * <ul>
- *   <li>The generated code for a binding requires an instance of a type that is generated in the
- *       root component compilation unit.
- *   <li>A {@linkplain ModifiableBindingType#BINDS_METHOD_WITH_MISSING_DEPENDENCY {@code @Binds}
- *       method's dependency is missing} in a subcomponent.
- * </ul>
- */
-final class DeferredModifiableBindingExpression extends ModifiableAbstractMethodBindingExpression {
-  private final ComponentImplementation componentImplementation;
-  private final ContributionBinding binding;
-  private final BindingRequest request;
-
-  DeferredModifiableBindingExpression(
-      ComponentImplementation componentImplementation,
-      ModifiableBindingType modifiableBindingType,
-      ContributionBinding binding,
-      BindingRequest request,
-      Optional<ModifiableBindingMethod> matchingModifiableBindingMethod,
-      Optional<ComponentMethodDescriptor> matchingComponentMethod,
-      DaggerTypes types) {
-    super(
-        componentImplementation,
-        modifiableBindingType,
-        request,
-        matchingModifiableBindingMethod,
-        matchingComponentMethod,
-        types);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.binding = checkNotNull(binding);
-    this.request = checkNotNull(request);
-  }
-
-  @Override
-  String chooseMethodName() {
-    return componentImplementation.getUniqueMethodName(request);
-  }
-
-  @Override
-  protected TypeMirror contributedType() {
-    return binding.contributedType();
-  }
-}
diff --git a/java/dagger/internal/codegen/DelegateBindingExpression.java b/java/dagger/internal/codegen/DelegateBindingExpression.java
deleted file mode 100644
index 8cdf6d1..0000000
--- a/java/dagger/internal/codegen/DelegateBindingExpression.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.RequestKinds.requestType;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static dagger.model.BindingKind.DELEGATE;
-
-import com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.RequestKind;
-import javax.lang.model.type.TypeMirror;
-
-/** A {@link BindingExpression} for {@code @Binds} methods. */
-final class DelegateBindingExpression extends BindingExpression {
-  private final ContributionBinding binding;
-  private final RequestKind requestKind;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-  private final BindsTypeChecker bindsTypeChecker;
-
-  DelegateBindingExpression(
-      ResolvedBindings resolvedBindings,
-      RequestKind requestKind,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      DaggerElements elements) {
-    this.binding = checkNotNull(resolvedBindings.contributionBinding());
-    this.requestKind = checkNotNull(requestKind);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-    this.types = checkNotNull(types);
-    this.bindsTypeChecker = new BindsTypeChecker(types, elements);
-  }
-
-  /**
-   * Returns {@code true} if the {@code @Binds} binding's scope is stronger than the scope of the
-   * binding it depends on.
-   */
-  static boolean isBindsScopeStrongerThanDependencyScope(
-      ResolvedBindings resolvedBindings, BindingGraph graph) {
-    ContributionBinding bindsBinding = resolvedBindings.contributionBinding();
-    checkArgument(bindsBinding.kind().equals(DELEGATE));
-    Binding dependencyBinding =
-        graph
-            .contributionBindings()
-            .get(getOnlyElement(bindsBinding.dependencies()).key())
-            .binding();
-    ScopeKind bindsScope = ScopeKind.get(bindsBinding, graph);
-    ScopeKind dependencyScope = ScopeKind.get(dependencyBinding, graph);
-    return bindsScope.isStrongerScopeThan(dependencyScope);
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    Expression delegateExpression =
-        componentBindingExpressions.getDependencyExpression(
-            bindingRequest(getOnlyElement(binding.dependencies()).key(), requestKind),
-            requestingClass);
-
-    TypeMirror contributedType = binding.contributedType();
-    switch (requestKind) {
-      case INSTANCE:
-        return instanceRequiresCast(delegateExpression, requestingClass)
-            ? delegateExpression.castTo(contributedType)
-            : delegateExpression;
-      default:
-        return castToRawTypeIfNecessary(
-            delegateExpression, requestType(requestKind, contributedType, types));
-    }
-  }
-
-  private boolean instanceRequiresCast(Expression delegateExpression, ClassName requestingClass) {
-    // delegateExpression.type() could be Object if expression is satisfied with a raw
-    // Provider's get() method.
-    return !bindsTypeChecker.isAssignable(
-        delegateExpression.type(), binding.contributedType(), binding.contributionType())
-        && isTypeAccessibleFrom(binding.contributedType(), requestingClass.packageName());
-  }
-
-  /**
-   * If {@code delegateExpression} can be assigned to {@code desiredType} safely, then {@code
-   * delegateExpression} is returned unchanged. If the {@code delegateExpression} is already a raw
-   * type, returns {@code delegateExpression} as well, as casting would have no effect. Otherwise,
-   * returns a {@link Expression#castTo(TypeMirror) casted} version of {@code delegateExpression}
-   * to the raw type of {@code desiredType}.
-   */
-  // TODO(ronshapiro): this probably can be generalized for usage in InjectionMethods
-  private Expression castToRawTypeIfNecessary(
-      Expression delegateExpression, TypeMirror desiredType) {
-    if (types.isAssignable(delegateExpression.type(), desiredType)) {
-      return delegateExpression;
-    }
-    return delegateExpression.castTo(types.erasure(desiredType));
-  }
-
-  private enum ScopeKind {
-    UNSCOPED,
-    SINGLE_CHECK,
-    DOUBLE_CHECK,
-    ;
-
-    static ScopeKind get(Binding binding, BindingGraph graph) {
-      return binding
-          .scope()
-          .map(scope -> scope.isReusable() ? SINGLE_CHECK : DOUBLE_CHECK)
-          .orElse(UNSCOPED);
-    }
-
-    boolean isStrongerScopeThan(ScopeKind other) {
-      return this.ordinal() > other.ordinal();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DelegateDeclaration.java b/java/dagger/internal/codegen/DelegateDeclaration.java
deleted file mode 100644
index 67991de..0000000
--- a/java/dagger/internal/codegen/DelegateDeclaration.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.MapKeys.getMapKey;
-import static dagger.internal.codegen.MoreAnnotationMirrors.wrapOptionalInEquivalence;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.Iterables;
-import dagger.Binds;
-import dagger.internal.codegen.ContributionType.HasContributionType;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ExecutableType;
-
-/**
- * The declaration for a delegate binding established by a {@link Binds} method.
- */
-@AutoValue
-abstract class DelegateDeclaration extends BindingDeclaration implements HasContributionType {
-  abstract DependencyRequest delegateRequest();
-
-  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedMapKey();
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-
-  static final class Factory {
-    private final DaggerTypes types;
-    private final KeyFactory keyFactory;
-    private final DependencyRequestFactory dependencyRequestFactory;
-
-    @Inject
-    Factory(
-        DaggerTypes types,
-        KeyFactory keyFactory,
-        DependencyRequestFactory dependencyRequestFactory) {
-      this.types = types;
-      this.keyFactory = keyFactory;
-      this.dependencyRequestFactory = dependencyRequestFactory;
-    }
-
-    DelegateDeclaration create(
-        ExecutableElement bindsMethod, TypeElement contributingModule) {
-      checkArgument(MoreElements.isAnnotationPresent(bindsMethod, Binds.class));
-      ExecutableType resolvedMethod =
-          MoreTypes.asExecutable(
-              types.asMemberOf(MoreTypes.asDeclared(contributingModule.asType()), bindsMethod));
-      DependencyRequest delegateRequest =
-          dependencyRequestFactory.forRequiredResolvedVariable(
-              Iterables.getOnlyElement(bindsMethod.getParameters()),
-              Iterables.getOnlyElement(resolvedMethod.getParameterTypes()));
-      return new AutoValue_DelegateDeclaration(
-          ContributionType.fromBindingElement(bindsMethod),
-          keyFactory.forBindsMethod(bindsMethod, contributingModule),
-          Optional.<Element>of(bindsMethod),
-          Optional.of(contributingModule),
-          delegateRequest,
-          wrapOptionalInEquivalence(getMapKey(bindsMethod)));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DelegatingFrameworkInstanceCreationExpression.java b/java/dagger/internal/codegen/DelegatingFrameworkInstanceCreationExpression.java
deleted file mode 100644
index 7524cdf..0000000
--- a/java/dagger/internal/codegen/DelegatingFrameworkInstanceCreationExpression.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.model.DependencyRequest;
-
-/** A framework instance creation expression for a {@link dagger.Binds @Binds} binding. */
-final class DelegatingFrameworkInstanceCreationExpression
-    implements FrameworkInstanceCreationExpression {
-
-  private final ContributionBinding binding;
-  private final ComponentImplementation componentImplementation;
-  private final ComponentBindingExpressions componentBindingExpressions;
-
-  DelegatingFrameworkInstanceCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    DependencyRequest dependency = getOnlyElement(binding.dependencies());
-    return CodeBlocks.cast(
-        componentBindingExpressions
-            .getDependencyExpression(
-                bindingRequest(dependency.key(), binding.frameworkType()),
-                componentImplementation.name())
-            .codeBlock(),
-        binding.frameworkType().frameworkClass());
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyCycleValidator.java b/java/dagger/internal/codegen/DependencyCycleValidator.java
deleted file mode 100644
index d5d4b62..0000000
--- a/java/dagger/internal/codegen/DependencyCycleValidator.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Iterables.getLast;
-import static com.google.common.collect.Iterables.limit;
-import static com.google.common.collect.Iterables.skip;
-import static com.google.common.collect.Sets.newHashSetWithExpectedSize;
-import static dagger.internal.codegen.DaggerGraphs.shortestPath;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.RequestKinds.extractKeyType;
-import static dagger.internal.codegen.RequestKinds.getRequestKind;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.graph.EndpointPair;
-import com.google.common.graph.ImmutableNetwork;
-import com.google.common.graph.MutableNetwork;
-import com.google.common.graph.NetworkBuilder;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.Node;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import dagger.model.RequestKind;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/** Reports errors for dependency cycles. */
-final class DependencyCycleValidator implements BindingGraphPlugin {
-
-  private final DependencyRequestFormatter dependencyRequestFormatter;
-
-  @Inject
-  DependencyCycleValidator(DependencyRequestFormatter dependencyRequestFormatter) {
-    this.dependencyRequestFormatter = dependencyRequestFormatter;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/DependencyCycle";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    ImmutableNetwork<Node, DependencyEdge> dependencyGraph =
-        nonCycleBreakingDependencyGraph(bindingGraph);
-    // Check each endpoint pair only once, no matter how many parallel edges connect them.
-    Set<EndpointPair<Node>> dependencyEndpointPairs = dependencyGraph.asGraph().edges();
-    Set<EndpointPair<Node>> visited = newHashSetWithExpectedSize(dependencyEndpointPairs.size());
-    for (EndpointPair<Node> endpointPair : dependencyEndpointPairs) {
-      cycleContainingEndpointPair(endpointPair, dependencyGraph, visited)
-          .ifPresent(cycle -> reportCycle(cycle, bindingGraph, diagnosticReporter));
-    }
-  }
-
-  private Optional<Cycle<Node>> cycleContainingEndpointPair(
-      EndpointPair<Node> endpoints,
-      ImmutableNetwork<Node, DependencyEdge> dependencyGraph,
-      Set<EndpointPair<Node>> visited) {
-    if (!visited.add(endpoints)) {
-      // don't recheck endpoints we already know are part of a cycle
-      return Optional.empty();
-    }
-
-    // If there's a path from the target back to the source, there's a cycle.
-    ImmutableList<Node> cycleNodes =
-        shortestPath(dependencyGraph, endpoints.target(), endpoints.source());
-    if (cycleNodes.isEmpty()) {
-      return Optional.empty();
-    }
-
-    Cycle<Node> cycle = Cycle.fromPath(cycleNodes);
-    visited.addAll(cycle.endpointPairs()); // no need to check any edge in this cycle again
-    return Optional.of(cycle);
-  }
-
-  /**
-   * Reports a dependency cycle at the dependency into the cycle that is closest to an entry point.
-   *
-   * <p>For cycles found in reachable binding graphs, looks for the shortest path from the component
-   * that contains the cycle (all bindings in a cycle must be in the same component; see below) to
-   * some binding in the cycle. Then looks for the last dependency in that path that is not in the
-   * cycle; that is the dependency that will be reported, so that the dependency trace will end just
-   * before the cycle.
-   *
-   * <p>For cycles found during full binding graph validation, just reports the component that
-   * contains the cycle.
-   *
-   * <p>Proof (by counterexample) that all bindings in a cycle must be in the same component: Assume
-   * one binding in the cycle is in a parent component. Bindings cannot depend on bindings in child
-   * components, so that binding cannot depend on the next binding in the cycle.
-   */
-  private void reportCycle(
-      Cycle<Node> cycle, BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    if (bindingGraph.isFullBindingGraph()) {
-      diagnosticReporter.reportComponent(
-          ERROR,
-          bindingGraph.componentNode(cycle.nodes().asList().get(0).componentPath()).get(),
-          errorMessage(cycle, bindingGraph));
-      return;
-    }
-
-    ImmutableList<Node> path = shortestPathToCycleFromAnEntryPoint(cycle, bindingGraph);
-    Node cycleStartNode = path.get(path.size() - 1);
-    Node previousNode = path.get(path.size() - 2);
-    DependencyEdge dependencyToReport =
-        chooseDependencyEdgeConnecting(previousNode, cycleStartNode, bindingGraph);
-    diagnosticReporter.reportDependency(
-        ERROR, dependencyToReport, errorMessage(cycle.shift(cycleStartNode), bindingGraph));
-  }
-
-  private ImmutableList<Node> shortestPathToCycleFromAnEntryPoint(
-      Cycle<Node> cycle, BindingGraph bindingGraph) {
-    Node someCycleNode = cycle.nodes().asList().get(0);
-    ComponentNode componentContainingCycle =
-        bindingGraph.componentNode(someCycleNode.componentPath()).get();
-    ImmutableList<Node> pathToCycle =
-        shortestPath(bindingGraph.network(), componentContainingCycle, someCycleNode);
-    return subpathToCycle(pathToCycle, cycle);
-  }
-
-  /**
-   * Returns the subpath from the head of {@code path} to the first node in {@code path} that's in
-   * the cycle.
-   */
-  private ImmutableList<Node> subpathToCycle(ImmutableList<Node> path, Cycle<Node> cycle) {
-    ImmutableList.Builder<Node> subpath = ImmutableList.builder();
-    for (Node node : path) {
-      subpath.add(node);
-      if (cycle.nodes().contains(node)) {
-        return subpath.build();
-      }
-    }
-    throw new IllegalArgumentException(
-        "path " + path + " doesn't contain any nodes in cycle " + cycle);
-  }
-
-  private String errorMessage(Cycle<Node> cycle, BindingGraph graph) {
-    StringBuilder message = new StringBuilder("Found a dependency cycle:");
-    ImmutableList<DependencyRequest> cycleRequests =
-        cycle.endpointPairs().stream()
-            // TODO(dpb): Would be nice to take the dependency graph here.
-            .map(endpointPair -> nonCycleBreakingEdge(endpointPair, graph))
-            .map(DependencyEdge::dependencyRequest)
-            .collect(toImmutableList())
-            .reverse();
-    dependencyRequestFormatter.formatIndentedList(message, cycleRequests, 0);
-    return message.toString();
-  }
-
-  /**
-   * Returns one of the edges between two nodes that doesn't {@linkplain
-   * #breaksCycle(DependencyEdge, BindingGraph) break} a cycle.
-   */
-  private DependencyEdge nonCycleBreakingEdge(EndpointPair<Node> endpointPair, BindingGraph graph) {
-    return graph.network().edgesConnecting(endpointPair.source(), endpointPair.target()).stream()
-        .flatMap(instancesOf(DependencyEdge.class))
-        .filter(edge -> !breaksCycle(edge, graph))
-        .findFirst()
-        .get();
-  }
-
-  private boolean breaksCycle(DependencyEdge edge, BindingGraph graph) {
-    if (edge.dependencyRequest().key().multibindingContributionIdentifier().isPresent()) {
-      return false;
-    }
-    if (breaksCycle(edge.dependencyRequest().key().type(), edge.dependencyRequest().kind())) {
-      return true;
-    }
-    Node target = graph.network().incidentNodes(edge).target();
-    if (target instanceof dagger.model.Binding
-        && ((dagger.model.Binding) target).kind().equals(BindingKind.OPTIONAL)) {
-      /* For @BindsOptionalOf bindings, unwrap the type inside the Optional. If the unwrapped type
-       * breaks the cycle, so does the optional binding. */
-      TypeMirror optionalValueType = OptionalType.from(edge.dependencyRequest().key()).valueType();
-      RequestKind requestKind = getRequestKind(optionalValueType);
-      return breaksCycle(extractKeyType(requestKind, optionalValueType), requestKind);
-    }
-    return false;
-  }
-
-  private boolean breaksCycle(TypeMirror requestedType, RequestKind requestKind) {
-    switch (requestKind) {
-      case PROVIDER:
-      case LAZY:
-      case PROVIDER_OF_LAZY:
-        return true;
-
-      case INSTANCE:
-        if (MapType.isMap(requestedType)) {
-          MapType mapType = MapType.from(requestedType);
-          return !mapType.isRawType() && mapType.valuesAreTypeOf(Provider.class);
-        }
-        // fall through
-
-      default:
-        return false;
-    }
-  }
-
-  private DependencyEdge chooseDependencyEdgeConnecting(
-      Node source, Node target, BindingGraph bindingGraph) {
-    return bindingGraph.network().edgesConnecting(source, target).stream()
-        .flatMap(instancesOf(DependencyEdge.class))
-        .findFirst()
-        .get();
-  }
-
-  /** Returns the subgraph containing only {@link DependencyEdge}s that would not break a cycle. */
-  // TODO(dpb): Return a network containing only Binding nodes.
-  private ImmutableNetwork<Node, DependencyEdge> nonCycleBreakingDependencyGraph(
-      BindingGraph bindingGraph) {
-    MutableNetwork<Node, DependencyEdge> dependencyNetwork =
-        NetworkBuilder.from(bindingGraph.network())
-            .expectedNodeCount(bindingGraph.network().nodes().size())
-            .expectedEdgeCount(bindingGraph.dependencyEdges().size())
-            .build();
-    bindingGraph.dependencyEdges().stream()
-        .filter(edge -> !breaksCycle(edge, bindingGraph))
-        .forEach(
-            edge -> {
-              EndpointPair<Node> endpoints = bindingGraph.network().incidentNodes(edge);
-              dependencyNetwork.addEdge(endpoints.source(), endpoints.target(), edge);
-            });
-    return ImmutableNetwork.copyOf(dependencyNetwork);
-  }
-
-  /**
-   * An ordered set of endpoint pairs representing the edges in the cycle. The target of each pair
-   * is the source of the next pair. The target of the last pair is the source of the first pair.
-   */
-  @AutoValue
-  abstract static class Cycle<N> {
-    /**
-     * The ordered set of endpoint pairs representing the edges in the cycle. The target of each
-     * pair is the source of the next pair. The target of the last pair is the source of the first
-     * pair.
-     */
-    abstract ImmutableSet<EndpointPair<N>> endpointPairs();
-
-    /** Returns the nodes that participate in the cycle. */
-    ImmutableSet<N> nodes() {
-      return endpointPairs().stream()
-          .flatMap(pair -> Stream.of(pair.source(), pair.target()))
-          .collect(toImmutableSet());
-    }
-
-    /** Returns the number of edges in the cycle. */
-    int size() {
-      return endpointPairs().size();
-    }
-
-    /**
-     * Shifts this cycle so that it starts with a specific node.
-     *
-     * @return a cycle equivalent to this one but whose first pair starts with {@code startNode}
-     */
-    Cycle<N> shift(N startNode) {
-      int startIndex = Iterables.indexOf(endpointPairs(), pair -> pair.source().equals(startNode));
-      checkArgument(
-          startIndex >= 0, "startNode (%s) is not part of this cycle: %s", startNode, this);
-      if (startIndex == 0) {
-        return this;
-      }
-      ImmutableSet.Builder<EndpointPair<N>> shifted = ImmutableSet.builder();
-      shifted.addAll(skip(endpointPairs(), startIndex));
-      shifted.addAll(limit(endpointPairs(), size() - startIndex));
-      return new AutoValue_DependencyCycleValidator_Cycle<>(shifted.build());
-    }
-
-    @Override
-    public final String toString() {
-      return endpointPairs().toString();
-    }
-
-    /**
-     * Creates a {@link Cycle} from a nonempty list of nodes, assuming there is an edge between each
-     * pair of nodes as well as an edge from the last node to the first.
-     */
-    static <N> Cycle<N> fromPath(List<N> nodes) {
-      checkArgument(!nodes.isEmpty());
-      ImmutableSet.Builder<EndpointPair<N>> cycle = ImmutableSet.builder();
-      cycle.add(EndpointPair.ordered(getLast(nodes), nodes.get(0)));
-      for (int i = 0; i < nodes.size() - 1; i++) {
-        cycle.add(EndpointPair.ordered(nodes.get(i), nodes.get(i + 1)));
-      }
-      return new AutoValue_DependencyCycleValidator_Cycle<>(cycle.build());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyEdgeImpl.java b/java/dagger/internal/codegen/DependencyEdgeImpl.java
deleted file mode 100644
index 64b0845..0000000
--- a/java/dagger/internal/codegen/DependencyEdgeImpl.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.DependencyRequest;
-
-/** An implementation of {@link DependencyEdge}. */
-final class DependencyEdgeImpl implements DependencyEdge {
-
-  private final DependencyRequest dependencyRequest;
-  private final boolean entryPoint;
-
-  DependencyEdgeImpl(DependencyRequest dependencyRequest, boolean entryPoint) {
-    this.dependencyRequest = dependencyRequest;
-    this.entryPoint = entryPoint;
-  }
-
-  @Override
-  public DependencyRequest dependencyRequest() {
-    return dependencyRequest;
-  }
-
-  @Override
-  public boolean isEntryPoint() {
-    return entryPoint;
-  }
-
-  @Override
-  public String toString() {
-    String string =
-        dependencyRequest
-            .requestElement()
-            .map(ElementFormatter::elementToString)
-            .orElseGet(
-                () ->
-                    "synthetic request for "
-                        + dependencyRequest.kind().format(dependencyRequest.key()));
-    return entryPoint ? string + " (entry point)" : string;
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyMethodProducerCreationExpression.java b/java/dagger/internal/codegen/DependencyMethodProducerCreationExpression.java
deleted file mode 100644
index b42f9c4..0000000
--- a/java/dagger/internal/codegen/DependencyMethodProducerCreationExpression.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
-import static dagger.internal.codegen.javapoet.TypeNames.dependencyMethodProducerOf;
-import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf;
-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 com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-
-/**
- * A {@link dagger.producers.Producer} creation expression for a production method on a production
- * component's {@linkplain dagger.producers.ProductionComponent#dependencies()} dependency} that
- * returns a {@link com.google.common.util.concurrent.ListenableFuture}.
- */
-// TODO(dpb): Resolve with DependencyMethodProviderCreationExpression.
-final class DependencyMethodProducerCreationExpression
-    implements FrameworkInstanceCreationExpression {
-  private final ContributionBinding binding;
-  private final ComponentImplementation componentImplementation;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-  private final BindingGraph graph;
-
-  DependencyMethodProducerCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentRequirementExpressions componentRequirementExpressions,
-      BindingGraph graph) {
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions);
-    this.graph = checkNotNull(graph);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    ComponentRequirement dependency =
-        graph.componentDescriptor().getDependencyThatDefinesMethod(binding.bindingElement().get());
-    FieldSpec dependencyField =
-        FieldSpec.builder(
-                ClassName.get(dependency.typeElement()), dependency.variableName(), PRIVATE, FINAL)
-            .initializer(
-                componentRequirementExpressions.getExpressionDuringInitialization(
-                    dependency,
-                    // This isn't a real class name, but we want the requesting class for the
-                    // expression to *not* be the same class as the component implementation,
-                    // because it isn't... it's an anonymous inner class.
-                    // TODO(cgdecker): If we didn't use an anonymous inner class here but instead
-                    // generated a named nested class as with
-                    // DependencyMethodProviderCreationExpression, we wouldn't need to deal with
-                    // this and might be able to avoid potentially creating an extra field in the
-                    // component?
-                    componentImplementation.name().nestedClass("Anonymous")))
-            .build();
-    // TODO(b/70395982): Explore using a private static type instead of an anonymous class.
-    TypeName keyType = TypeName.get(binding.key().type());
-    return CodeBlock.of(
-        "$L",
-        anonymousClassBuilder("")
-            .superclass(dependencyMethodProducerOf(keyType))
-            .addField(dependencyField)
-            .addMethod(
-                methodBuilder("callDependencyMethod")
-                    .addAnnotation(Override.class)
-                    .addModifiers(PUBLIC)
-                    .returns(listenableFutureOf(keyType))
-                    .addStatement(
-                        "return $N.$L()",
-                        dependencyField,
-                        binding.bindingElement().get().getSimpleName())
-                    .build())
-            .build());
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyMethodProviderCreationExpression.java b/java/dagger/internal/codegen/DependencyMethodProviderCreationExpression.java
deleted file mode 100644
index 8532481..0000000
--- a/java/dagger/internal/codegen/DependencyMethodProviderCreationExpression.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-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.ComponentImplementation.TypeSpecKind.COMPONENT_PROVISION_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-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;
-
-import com.google.auto.common.MoreTypes;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import javax.lang.model.element.Element;
-
-/**
- * A {@link javax.inject.Provider} creation expression for a provision method on a component's
- * {@linkplain dagger.Component#dependencies()} dependency}.
- */
-// TODO(dpb): Resolve with DependencyMethodProducerCreationExpression.
-final class DependencyMethodProviderCreationExpression
-    implements FrameworkInstanceCreationExpression {
-
-  private final ComponentImplementation componentImplementation;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-  private final CompilerOptions compilerOptions;
-  private final BindingGraph graph;
-  private final ContributionBinding binding;
-
-  DependencyMethodProviderCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentRequirementExpressions componentRequirementExpressions,
-      CompilerOptions compilerOptions,
-      BindingGraph graph) {
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions);
-    this.compilerOptions = checkNotNull(compilerOptions);
-    this.graph = checkNotNull(graph);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    // TODO(sameb): The Provider.get() throws a very vague NPE.  The stack trace doesn't
-    // help to figure out what the method or return type is.  If we include a string
-    // of the return type or method name in the error message, that can defeat obfuscation.
-    // We can easily include the raw type (no generics) + annotation type (no values),
-    // using .class & String.format -- but that wouldn't be the whole story.
-    // What should we do?
-    CodeBlock invocation =
-        ComponentProvisionBindingExpression.maybeCheckForNull(
-            (ProvisionBinding) binding,
-            compilerOptions,
-            CodeBlock.of(
-                "$N.$N()", dependency().variableName(), provisionMethod().getSimpleName()));
-    ClassName dependencyClassName = ClassName.get(dependency().typeElement());
-    TypeName keyType = TypeName.get(binding.key().type());
-    MethodSpec.Builder getMethod =
-        methodBuilder("get")
-            .addAnnotation(Override.class)
-            .addModifiers(PUBLIC)
-            .returns(keyType)
-            .addStatement("return $L", invocation);
-    if (binding.nullableType().isPresent()) {
-      getMethod.addAnnotation(ClassName.get(MoreTypes.asTypeElement(binding.nullableType().get())));
-    }
-    componentImplementation.addType(
-        COMPONENT_PROVISION_FACTORY,
-        classBuilder(factoryClassName())
-            .addSuperinterface(providerOf(keyType))
-            .addModifiers(PRIVATE, STATIC)
-            .addField(dependencyClassName, dependency().variableName(), PRIVATE, FINAL)
-            .addMethod(
-                constructorBuilder()
-                    .addParameter(dependencyClassName, dependency().variableName())
-                    .addStatement("this.$1L = $1L", dependency().variableName())
-                    .build())
-            .addMethod(getMethod.build())
-            .build());
-    return CodeBlock.of(
-        "new $T($L)",
-        factoryClassName(),
-        componentRequirementExpressions.getExpressionDuringInitialization(
-            dependency(), componentImplementation.name()));
-  }
-
-  private ClassName factoryClassName() {
-    String factoryName =
-        ClassName.get(dependency().typeElement()).toString().replace('.', '_')
-            + "_"
-            + binding.bindingElement().get().getSimpleName();
-    return componentImplementation.name().nestedClass(factoryName);
-  }
-
-  private ComponentRequirement dependency() {
-    return graph.componentDescriptor().getDependencyThatDefinesMethod(provisionMethod());
-  }
-
-  private Element provisionMethod() {
-    return binding.bindingElement().get();
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyRequestFactory.java b/java/dagger/internal/codegen/DependencyRequestFactory.java
deleted file mode 100644
index 3ad12e2..0000000
--- a/java/dagger/internal/codegen/DependencyRequestFactory.java
+++ /dev/null
@@ -1,237 +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.auto.common.MoreTypes.isTypeOf;
-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 com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ConfigurationAnnotations.getNullableType;
-import static dagger.internal.codegen.RequestKinds.extractKeyType;
-import static dagger.internal.codegen.RequestKinds.frameworkClass;
-import static dagger.internal.codegen.RequestKinds.getRequestKind;
-import static dagger.model.RequestKind.FUTURE;
-import static dagger.model.RequestKind.INSTANCE;
-import static dagger.model.RequestKind.MEMBERS_INJECTION;
-import static dagger.model.RequestKind.PRODUCER;
-import static dagger.model.RequestKind.PROVIDER;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.Lazy;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.List;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Factory for {@link DependencyRequest}s.
- *
- * <p>Any factory method may throw {@link TypeNotPresentException} if a type is not available, which
- * may mean that the type will be generated in a later round of processing.
- */
-final class DependencyRequestFactory {
-  private final KeyFactory keyFactory;
-  private final DaggerTypes types;
-
-  @Inject
-  DependencyRequestFactory(KeyFactory keyFactory, DaggerTypes types) {
-    this.keyFactory = keyFactory;
-    this.types = types;
-  }
-
-  ImmutableSet<DependencyRequest> forRequiredResolvedVariables(
-      List<? extends VariableElement> variables, List<? extends TypeMirror> resolvedTypes) {
-    checkState(resolvedTypes.size() == variables.size());
-    ImmutableSet.Builder<DependencyRequest> builder = ImmutableSet.builder();
-    for (int i = 0; i < variables.size(); i++) {
-      builder.add(forRequiredResolvedVariable(variables.get(i), resolvedTypes.get(i)));
-    }
-    return builder.build();
-  }
-
-  /**
-   * Creates synthetic dependency requests for each individual multibinding contribution in {@code
-   * multibindingContributions}.
-   */
-  ImmutableSet<DependencyRequest> forMultibindingContributions(
-      Key multibindingKey, Iterable<ContributionBinding> multibindingContributions) {
-    ImmutableSet.Builder<DependencyRequest> requests = ImmutableSet.builder();
-    for (ContributionBinding multibindingContribution : multibindingContributions) {
-      requests.add(forMultibindingContribution(multibindingKey, multibindingContribution));
-    }
-    return requests.build();
-  }
-
-  /** Creates a synthetic dependency request for one individual {@code multibindingContribution}. */
-  private DependencyRequest forMultibindingContribution(
-      Key multibindingKey, ContributionBinding multibindingContribution) {
-    checkArgument(
-        multibindingContribution.key().multibindingContributionIdentifier().isPresent(),
-        "multibindingContribution's key must have a multibinding contribution identifier: %s",
-        multibindingContribution);
-    return DependencyRequest.builder()
-        .kind(multibindingContributionRequestKind(multibindingKey, multibindingContribution))
-        .key(multibindingContribution.key())
-        .build();
-  }
-
-  // TODO(b/28555349): support PROVIDER_OF_LAZY here too
-  private static final ImmutableSet<RequestKind> WRAPPING_MAP_VALUE_FRAMEWORK_TYPES =
-      ImmutableSet.of(PROVIDER, PRODUCER);
-
-  private RequestKind multibindingContributionRequestKind(
-      Key multibindingKey, ContributionBinding multibindingContribution) {
-    switch (multibindingContribution.contributionType()) {
-      case MAP:
-        MapType mapType = MapType.from(multibindingKey);
-        for (RequestKind kind : WRAPPING_MAP_VALUE_FRAMEWORK_TYPES) {
-          if (mapType.valuesAreTypeOf(frameworkClass(kind))) {
-            return kind;
-          }
-        }
-        // fall through
-      case SET:
-      case SET_VALUES:
-        return INSTANCE;
-      case UNIQUE:
-        throw new IllegalArgumentException(
-            "multibindingContribution must be a multibinding: " + multibindingContribution);
-    }
-    throw new AssertionError(multibindingContribution.toString());
-  }
-
-  DependencyRequest forRequiredResolvedVariable(
-      VariableElement variableElement, TypeMirror resolvedType) {
-    checkNotNull(variableElement);
-    checkNotNull(resolvedType);
-    Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(variableElement);
-    return newDependencyRequest(variableElement, resolvedType, qualifier);
-  }
-
-  DependencyRequest forComponentProvisionMethod(
-      ExecutableElement provisionMethod, ExecutableType provisionMethodType) {
-    checkNotNull(provisionMethod);
-    checkNotNull(provisionMethodType);
-    checkArgument(
-        provisionMethod.getParameters().isEmpty(),
-        "Component provision methods must be empty: %s",
-        provisionMethod);
-    Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(provisionMethod);
-    return newDependencyRequest(provisionMethod, provisionMethodType.getReturnType(), qualifier);
-  }
-
-  DependencyRequest forComponentProductionMethod(
-      ExecutableElement productionMethod, ExecutableType productionMethodType) {
-    checkNotNull(productionMethod);
-    checkNotNull(productionMethodType);
-    checkArgument(
-        productionMethod.getParameters().isEmpty(),
-        "Component production methods must be empty: %s",
-        productionMethod);
-    TypeMirror type = productionMethodType.getReturnType();
-    Optional<AnnotationMirror> qualifier = InjectionAnnotations.getQualifier(productionMethod);
-    // Only a component production method can be a request for a ListenableFuture, so we
-    // special-case it here.
-    if (isTypeOf(ListenableFuture.class, type)) {
-      return DependencyRequest.builder()
-          .kind(FUTURE)
-          .key(keyFactory.forQualifiedType(qualifier, types.unwrapType(type)))
-          .requestElement(productionMethod)
-          .build();
-    } else {
-      return newDependencyRequest(productionMethod, type, qualifier);
-    }
-  }
-
-  DependencyRequest forComponentMembersInjectionMethod(
-      ExecutableElement membersInjectionMethod, ExecutableType membersInjectionMethodType) {
-    checkNotNull(membersInjectionMethod);
-    checkNotNull(membersInjectionMethodType);
-    Optional<AnnotationMirror> qualifier =
-        InjectionAnnotations.getQualifier(membersInjectionMethod);
-    checkArgument(!qualifier.isPresent());
-    TypeMirror membersInjectedType = getOnlyElement(membersInjectionMethodType.getParameterTypes());
-    return DependencyRequest.builder()
-        .kind(MEMBERS_INJECTION)
-        .key(keyFactory.forMembersInjectedType(membersInjectedType))
-        .requestElement(membersInjectionMethod)
-        .build();
-  }
-
-  DependencyRequest forProductionImplementationExecutor() {
-    return DependencyRequest.builder()
-        .kind(PROVIDER)
-        .key(keyFactory.forProductionImplementationExecutor())
-        .build();
-  }
-
-  DependencyRequest forProductionComponentMonitor() {
-    return DependencyRequest.builder()
-        .kind(PROVIDER)
-        .key(keyFactory.forProductionComponentMonitor())
-        .build();
-  }
-
-  /**
-   * Returns a synthetic request for the present value of an optional binding generated from a
-   * {@link dagger.BindsOptionalOf} declaration.
-   */
-  DependencyRequest forSyntheticPresentOptionalBinding(Key requestKey, RequestKind kind) {
-    Optional<Key> key = keyFactory.unwrapOptional(requestKey);
-    checkArgument(key.isPresent(), "not a request for optional: %s", requestKey);
-    return DependencyRequest.builder()
-        .kind(kind)
-        .key(key.get())
-        .isNullable(
-            allowsNull(getRequestKind(OptionalType.from(requestKey).valueType()), Optional.empty()))
-        .build();
-  }
-
-  private DependencyRequest newDependencyRequest(
-      Element requestElement, TypeMirror type, Optional<AnnotationMirror> qualifier) {
-    RequestKind requestKind = getRequestKind(type);
-    return DependencyRequest.builder()
-        .kind(requestKind)
-        .key(keyFactory.forQualifiedType(qualifier, extractKeyType(requestKind, type)))
-        .requestElement(requestElement)
-        .isNullable(allowsNull(requestKind, getNullableType(requestElement)))
-        .build();
-  }
-
-  /**
-   * Returns {@code true} if a given request element allows null values. {@link
-   * RequestKind#INSTANCE} requests must be annotated with {@code @Nullable} in order to allow null
-   * values. All other request kinds implicitly allow null values because they are are wrapped
-   * inside {@link Provider}, {@link Lazy}, etc.
-   */
-  private boolean allowsNull(RequestKind kind, Optional<DeclaredType> nullableType) {
-    return nullableType.isPresent() || !kind.equals(INSTANCE);
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyRequestFormatter.java b/java/dagger/internal/codegen/DependencyRequestFormatter.java
deleted file mode 100644
index 25becaf..0000000
--- a/java/dagger/internal/codegen/DependencyRequestFormatter.java
+++ /dev/null
@@ -1,151 +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 dagger.internal.codegen.ElementFormatter.elementToString;
-import static dagger.internal.codegen.RequestKinds.requestType;
-
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.producers.Produces;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementKindVisitor8;
-
-/**
- * Formats a {@link DependencyRequest} into a {@link String} suitable for an error message listing a
- * chain of dependencies.
- *
- * <dl>
- *   <dt>For component provision methods
- *   <dd>{@code @Qualifier SomeType is provided at\n ComponentType.method()}
- *   <dt>For component injection methods
- *   <dd>{@code SomeType is injected at\n ComponentType.method(foo)}
- *   <dt>For parameters to {@link Provides @Provides}, {@link Produces @Produces}, or {@link
- *       Inject @Inject} methods:
- *   <dd>{@code @Qualified ResolvedType is injected at\n EnclosingType.method([…, ]param[, …])}
- *   <dt>For parameters to {@link Inject @Inject} constructors:
- *   <dd>{@code @Qualified ResolvedType is injected at\n EnclosingType([…, ]param[, …])}
- *   <dt>For {@link Inject @Inject} fields:
- *   <dd>{@code @Qualified ResolvedType is injected at\n EnclosingType.field}
- * </dl>
- */
-final class DependencyRequestFormatter extends Formatter<DependencyRequest> {
-
-  private final DaggerTypes types;
-
-  @Inject
-  DependencyRequestFormatter(DaggerTypes types) {
-    this.types = types;
-  }
-
-  @Override
-  public String format(DependencyRequest request) {
-    return request
-        .requestElement()
-        .map(element -> element.accept(formatVisitor, request))
-        .orElse("");
-  }
-
-  /**
-   * Appends a newline and the formatted dependency request unless {@link
-   * #format(DependencyRequest)} returns the empty string.
-   */
-  @CanIgnoreReturnValue
-  StringBuilder appendFormatLine(StringBuilder builder, DependencyRequest dependencyRequest) {
-    String formatted = format(dependencyRequest);
-    if (!formatted.isEmpty()) {
-      builder.append('\n').append(formatted);
-    }
-    return builder;
-  }
-
-  private final ElementVisitor<String, DependencyRequest> formatVisitor =
-      new ElementKindVisitor8<String, DependencyRequest>() {
-
-        @Override
-        public String visitExecutableAsMethod(ExecutableElement method, DependencyRequest request) {
-          return INDENT
-              + request.key()
-              + " is "
-              + componentMethodRequestVerb(request)
-              + " at\n"
-              + DOUBLE_INDENT
-              + elementToString(method);
-        }
-
-        @Override
-        public String visitVariable(VariableElement variable, DependencyRequest request) {
-          TypeMirror requestedType = requestType(request.kind(), request.key().type(), types);
-          return INDENT
-              + formatQualifier(request.key().qualifier())
-              + requestedType
-              + " is injected at\n"
-              + DOUBLE_INDENT
-              + elementToString(variable);
-        }
-
-        @Override
-        public String visitType(TypeElement e, DependencyRequest request) {
-          return ""; // types by themselves provide no useful information.
-        }
-
-        @Override
-        protected String defaultAction(Element element, DependencyRequest request) {
-          throw new IllegalStateException(
-              "Invalid request " + element.getKind() + " element " + element);
-        }
-      };
-
-  private String formatQualifier(Optional<AnnotationMirror> maybeQualifier) {
-    return maybeQualifier.map(qualifier -> qualifier + " ").orElse("");
-  }
-
-  /**
-   * Returns the verb for a component method dependency request. Returns "produced", "provided", or
-   * "injected", depending on the kind of request.
-   */
-  private String componentMethodRequestVerb(DependencyRequest request) {
-    switch (request.kind()) {
-      case FUTURE:
-      case PRODUCER:
-        return "produced";
-
-      case INSTANCE:
-      case LAZY:
-      case PROVIDER:
-      case PROVIDER_OF_LAZY:
-        return "provided";
-
-      case MEMBERS_INJECTION:
-        return "injected";
-
-      case PRODUCED:
-        break;
-    }
-    throw new AssertionError("illegal request kind for method: " + request);
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyRequestValidator.java b/java/dagger/internal/codegen/DependencyRequestValidator.java
deleted file mode 100644
index 1a99818..0000000
--- a/java/dagger/internal/codegen/DependencyRequestValidator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.InjectionAnnotations.getQualifiers;
-import static dagger.internal.codegen.RequestKinds.extractKeyType;
-import static dagger.internal.codegen.RequestKinds.getRequestKind;
-import static javax.lang.model.type.TypeKind.WILDCARD;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.MembersInjector;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** Validation for dependency requests. */
-final class DependencyRequestValidator {
-  private final MembersInjectionValidator membersInjectionValidator;
-
-  @Inject
-  DependencyRequestValidator(MembersInjectionValidator membersInjectionValidator) {
-    this.membersInjectionValidator = membersInjectionValidator;
-  }
-
-  /**
-   * Adds an error if the given dependency request has more than one qualifier annotation or is a
-   * non-instance request with a wildcard type.
-   */
-  void validateDependencyRequest(
-      ValidationReport.Builder<?> report, Element requestElement, TypeMirror requestType) {
-    ImmutableSet<? extends AnnotationMirror> qualifiers = getQualifiers(requestElement);
-    if (qualifiers.size() > 1) {
-      for (AnnotationMirror qualifier : qualifiers) {
-        report.addError(
-            "A single dependency request may not use more than one @Qualifier",
-            requestElement,
-            qualifier);
-      }
-    }
-
-    TypeMirror keyType = extractKeyType(getRequestKind(requestType), requestType);
-    if (keyType.getKind().equals(WILDCARD)) {
-      // TODO(ronshapiro): Explore creating this message using RequestKinds.
-      report.addError(
-          "Dagger does not support injecting Provider<T>, Lazy<T>, Producer<T>, "
-              + "or Produced<T> when T is a wildcard type such as "
-              + keyType,
-          requestElement);
-    }
-    if (MoreTypes.isType(keyType) && MoreTypes.isTypeOf(MembersInjector.class, keyType)) {
-      DeclaredType membersInjectorType = MoreTypes.asDeclared(keyType);
-      if (membersInjectorType.getTypeArguments().isEmpty()) {
-        report.addError("Cannot inject a raw MembersInjector", requestElement);
-      } else {
-        report.addSubreport(
-            membersInjectionValidator.validateMembersInjectionRequest(
-                requestElement, membersInjectorType.getTypeArguments().get(0)));
-      }
-    }
-  }
-
-  /**
-   * Adds an error if the given dependency request is for a {@link dagger.producers.Producer} or
-   * {@link dagger.producers.Produced}.
-   *
-   * <p>Only call this when processing a provision binding.
-   */
-  // TODO(dpb): Should we disallow Producer entry points in non-production components?
-  void checkNotProducer(ValidationReport.Builder<?> report, VariableElement requestElement) {
-    TypeMirror requestType = requestElement.asType();
-    if (FrameworkTypes.isProducerType(requestType)) {
-      report.addError(
-          String.format(
-              "%s may only be injected in @Produces methods",
-              MoreTypes.asTypeElement(requestType).getSimpleName()),
-          requestElement);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DependencyVariableNamer.java b/java/dagger/internal/codegen/DependencyVariableNamer.java
deleted file mode 100644
index 21f2d32..0000000
--- a/java/dagger/internal/codegen/DependencyVariableNamer.java
+++ /dev/null
@@ -1,82 +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 dagger.internal.codegen.SourceFiles.simpleVariableName;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Ascii;
-import com.google.common.base.CaseFormat;
-import dagger.Lazy;
-import dagger.model.DependencyRequest;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.inject.Provider;
-
-/**
- * Picks a reasonable name for what we think is being provided from the variable name associated
- * with the {@link DependencyRequest}.  I.e. strips out words like "lazy" and "provider" if we
- * believe that those refer to {@link Lazy} and {@link Provider} rather than the type being
- * provided.
- */
-//TODO(gak): develop the heuristics to get better names
-final class DependencyVariableNamer {
-  private static final Pattern LAZY_PROVIDER_PATTERN = Pattern.compile("lazy(\\w+)Provider");
-
-  static String name(DependencyRequest dependency) {
-    if (!dependency.requestElement().isPresent()) {
-      return simpleVariableName(MoreTypes.asTypeElement(dependency.key().type()));
-    }
-
-    String variableName = dependency.requestElement().get().getSimpleName().toString();
-    if (Ascii.isUpperCase(variableName.charAt(0))) {
-      variableName = toLowerCamel(variableName);
-    }
-    switch (dependency.kind()) {
-      case INSTANCE:
-        return variableName;
-      case LAZY:
-        return variableName.startsWith("lazy") && !variableName.equals("lazy")
-            ? toLowerCamel(variableName.substring(4))
-            : variableName;
-      case PROVIDER_OF_LAZY:
-        Matcher matcher = LAZY_PROVIDER_PATTERN.matcher(variableName);
-        if (matcher.matches()) {
-          return toLowerCamel(matcher.group(1));
-        }
-        // fall through
-      case PROVIDER:
-        return variableName.endsWith("Provider") && !variableName.equals("Provider")
-            ? variableName.substring(0, variableName.length() - 8)
-            : variableName;
-      case PRODUCED:
-        return variableName.startsWith("produced") && !variableName.equals("produced")
-            ? toLowerCamel(variableName.substring(8))
-            : variableName;
-      case PRODUCER:
-        return variableName.endsWith("Producer") && !variableName.equals("Producer")
-            ? variableName.substring(0, variableName.length() - 8)
-            : variableName;
-      default:
-        throw new AssertionError();
-    }
-  }
-
-  private static String toLowerCamel(String name) {
-    return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, name);
-  }
-}
diff --git a/java/dagger/internal/codegen/DependsOnProductionExecutorValidator.java b/java/dagger/internal/codegen/DependsOnProductionExecutorValidator.java
deleted file mode 100644
index e611d22..0000000
--- a/java/dagger/internal/codegen/DependsOnProductionExecutorValidator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.DaggerStreams.instancesOf;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.MaybeBinding;
-import dagger.model.Key;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import javax.inject.Inject;
-
-/**
- * Reports an error on all bindings that depend explicitly on the {@code @Production Executor} key.
- */
-// TODO(dpb,beder): Validate this during @Inject/@Provides/@Produces validation.
-final class DependsOnProductionExecutorValidator implements BindingGraphPlugin {
-  private final CompilerOptions compilerOptions;
-  private final KeyFactory keyFactory;
-
-  @Inject
-  DependsOnProductionExecutorValidator(CompilerOptions compilerOptions, KeyFactory keyFactory) {
-    this.compilerOptions = compilerOptions;
-    this.keyFactory = keyFactory;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/DependsOnProductionExecutor";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    if (!compilerOptions.usesProducers()) {
-      return;
-    }
-
-    Key productionImplementationExecutorKey = keyFactory.forProductionImplementationExecutor();
-    Key productionExecutorKey = keyFactory.forProductionExecutor();
-
-    bindingGraph.network().nodes().stream()
-        .flatMap(instancesOf(MaybeBinding.class))
-        .filter(node -> node.key().equals(productionExecutorKey))
-        .flatMap(productionExecutor -> bindingGraph.requestingBindings(productionExecutor).stream())
-        .filter(binding -> !binding.key().equals(productionImplementationExecutorKey))
-        .forEach(binding -> reportError(diagnosticReporter, binding));
-  }
-
-  private void reportError(DiagnosticReporter diagnosticReporter, dagger.model.Binding binding) {
-    diagnosticReporter.reportBinding(
-        ERROR, binding, "%s may not depend on the production executor", binding.key());
-  }
-}
diff --git a/java/dagger/internal/codegen/DerivedFromFrameworkInstanceBindingExpression.java b/java/dagger/internal/codegen/DerivedFromFrameworkInstanceBindingExpression.java
deleted file mode 100644
index 4f2f622..0000000
--- a/java/dagger/internal/codegen/DerivedFromFrameworkInstanceBindingExpression.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-
-import com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import javax.lang.model.type.TypeMirror;
-
-/** A binding expression that depends on a framework instance. */
-final class DerivedFromFrameworkInstanceBindingExpression extends BindingExpression {
-
-  private final BindingRequest frameworkRequest;
-  private final RequestKind requestKind;
-  private final FrameworkType frameworkType;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-
-  DerivedFromFrameworkInstanceBindingExpression(
-      Key key,
-      FrameworkType frameworkType,
-      RequestKind requestKind,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types) {
-    this.frameworkRequest = bindingRequest(key, frameworkType);
-    this.requestKind = checkNotNull(requestKind);
-    this.frameworkType = checkNotNull(frameworkType);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-    this.types = checkNotNull(types);
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    return frameworkType.to(
-        requestKind,
-        componentBindingExpressions.getDependencyExpression(frameworkRequest, requestingClass),
-        types);
-  }
-
-  @Override
-  Expression getDependencyExpressionForComponentMethod(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    Expression frameworkInstance =
-        componentBindingExpressions.getDependencyExpressionForComponentMethod(
-            frameworkRequest, componentMethod, component);
-    Expression forRequestKind = frameworkType.to(requestKind, frameworkInstance, types);
-    TypeMirror rawReturnType = types.erasure(componentMethod.resolvedReturnType(types));
-    if (!types.isAssignable(forRequestKind.type(), rawReturnType)) {
-      checkState(
-          component.isAbstract(),
-          "FrameworkType.to() should always return an accessible type unless we're in "
-              + "ahead-of-time mode, where the framework instance type is erased since it's not "
-              + "publicly accessible, but the return type is accessible to the package. "
-              + "\n  Component: %s, method: %s",
-          component.name(),
-          componentMethod);
-      return forRequestKind.castTo(rawReturnType);
-    }
-    return forRequestKind;
-  }
-}
diff --git a/java/dagger/internal/codegen/DeserializedComponentImplementationBuilder.java b/java/dagger/internal/codegen/DeserializedComponentImplementationBuilder.java
deleted file mode 100644
index 45e99a8..0000000
--- a/java/dagger/internal/codegen/DeserializedComponentImplementationBuilder.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2019 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.auto.common.AnnotationMirrors.getAnnotationValue;
-import static com.google.auto.common.MoreElements.getAnnotationMirror;
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.MoreAnnotationValues.asAnnotationValues;
-import static dagger.internal.codegen.serialization.ProtoSerialization.fromAnnotationValue;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-import static javax.lang.model.util.ElementFilter.typesIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.ComponentDefinitionType;
-import dagger.internal.ConfigureInitializationParameters;
-import dagger.internal.ModifiableBinding;
-import dagger.internal.ModifiableModule;
-import dagger.internal.codegen.ComponentImplementation.ConfigureInitializationMethod;
-import dagger.internal.codegen.serialization.BindingRequestProto;
-import dagger.internal.codegen.serialization.ComponentRequirementProto;
-import dagger.internal.codegen.serialization.FrameworkTypeWrapper;
-import dagger.internal.codegen.serialization.KeyProto;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Reconstructs {@link ComponentImplementation}s that have already been compiled. Uses metadata
- * annotations on the generated type and it's methods to reconstitute the equivalent {@link
- * ComponentImplementation} state.
- */
-final class DeserializedComponentImplementationBuilder {
-  private final CompilerOptions compilerOptions;
-  private final ComponentCreatorImplementationFactory componentCreatorImplementationFactory;
-  private final TypeProtoConverter typeProtoConverter;
-  private final KeyFactory keyFactory;
-
-  @Inject
-  DeserializedComponentImplementationBuilder(
-      CompilerOptions compilerOptions,
-      ComponentCreatorImplementationFactory componentCreatorImplementationFactory,
-      TypeProtoConverter typeProtoConverter,
-      KeyFactory keyFactory) {
-    this.compilerOptions = compilerOptions;
-    this.componentCreatorImplementationFactory = componentCreatorImplementationFactory;
-    this.typeProtoConverter = typeProtoConverter;
-    this.keyFactory = keyFactory;
-  }
-
-  /** Creates a new {@link ComponentImplementation} from a compiled component. */
-  ComponentImplementation create(ComponentDescriptor component, TypeElement generatedComponent) {
-    Optional<ComponentImplementation> superclassImplementation =
-        deserializedSuperclassImplementation(
-            component, MoreTypes.asTypeElement(generatedComponent.getSuperclass()));
-
-    ComponentImplementation componentImplementation =
-        ComponentImplementation.forDeserializedComponent(
-            component,
-            ClassName.get(generatedComponent),
-            generatedComponent.getNestingKind(),
-            superclassImplementation,
-            compilerOptions);
-
-    componentImplementation.setCreatorImplementation(
-        superclassImplementation.isPresent()
-            ? Optional.empty()
-            : componentCreatorImplementationFactory.create(
-                componentImplementation, Optional.empty()));
-
-    // TODO(b/117833324): Consider omitting superclass implementations, so that only one instance of
-    // ComponentImplementation needs to be created (in most cases, we don't care about nested levels
-    // of superclass implementations, except for the base implementation). If that's possible, use
-    // getLocalAndInheritedMethods instead of getEnclosedElements() here.
-    for (ExecutableElement method : methodsIn(generatedComponent.getEnclosedElements())) {
-      getAnnotationMirror(method, ModifiableBinding.class)
-          .asSet()
-          .forEach(
-              annotation ->
-                  addModifiableBindingMethod(componentImplementation, method, annotation));
-
-      getAnnotationMirror(method, ModifiableModule.class)
-          .asSet()
-          .forEach(
-              annotation -> addModifiableModuleMethod(componentImplementation, method, annotation));
-
-      getAnnotationMirror(method, ConfigureInitializationParameters.class)
-          .asSet()
-          .forEach(
-              annotation ->
-                  setConfigureInitializationMethod(componentImplementation, method, annotation));
-    }
-
-    for (TypeElement nestedType : typesIn(generatedComponent.getEnclosedElements())) {
-      addChildImplementation(component, componentImplementation, nestedType);
-    }
-
-    return componentImplementation;
-  }
-
-  private Optional<ComponentImplementation> deserializedSuperclassImplementation(
-      ComponentDescriptor component, TypeElement superclassElement) {
-    return isAnnotationPresent(superclassElement, ComponentDefinitionType.class)
-        ? Optional.of(create(component, superclassElement))
-        : Optional.empty();
-  }
-
-  private void addModifiableBindingMethod(
-      ComponentImplementation componentImplementation,
-      ExecutableElement method,
-      AnnotationMirror metadataAnnotation) {
-    ModifiableBindingType modifiableBindingType =
-        ModifiableBindingType.valueOf(
-            getAnnotationValue(metadataAnnotation, "modifiableBindingType").getValue().toString());
-
-    BindingRequest request =
-        parseBindingRequest(getAnnotationValue(metadataAnnotation, "bindingRequest"));
-
-    ImmutableList<Key> multibindingContributions =
-        asAnnotationValues(getAnnotationValue(metadataAnnotation, "multibindingContributions"))
-            .stream()
-            .map(this::parseKey)
-            .collect(toImmutableList());
-
-    componentImplementation.addModifiableBindingMethod(
-        modifiableBindingType,
-        request,
-        method.getReturnType(),
-        methodDeclaration(method),
-        method.getModifiers().contains(FINAL));
-    componentImplementation.registerImplementedMultibindingKeys(request, multibindingContributions);
-  }
-
-  private BindingRequest fromProto(BindingRequestProto bindingRequest) {
-    Key key = keyFactory.fromProto(bindingRequest.getKey());
-    return bindingRequest.getFrameworkType().equals(FrameworkTypeWrapper.FrameworkType.UNKNOWN)
-        ? bindingRequest(key, RequestKind.valueOf(bindingRequest.getRequestKind().name()))
-        : bindingRequest(key, FrameworkType.valueOf(bindingRequest.getFrameworkType().name()));
-  }
-
-  /**
-   * Returns a {@link MethodSpec} for a {@link
-   * dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod}. The method contents
-   * are not relevant since this represents a method that has already been compiled.
-   *
-   * <p>Ideally this could be {@code MethodSpec.overriding(method).build()}, but that doesn't work
-   * for {@code final} methods
-   */
-  private MethodSpec methodDeclaration(ExecutableElement method) {
-    return methodBuilder(method.getSimpleName().toString())
-        .addModifiers(method.getModifiers())
-        .returns(TypeName.get(method.getReturnType()))
-        .build();
-  }
-
-  private void addModifiableModuleMethod(
-      ComponentImplementation componentImplementation,
-      ExecutableElement method,
-      AnnotationMirror metadataAnnotation) {
-    ComponentRequirement moduleRequirement =
-        parseComponentRequirement(getAnnotationValue(metadataAnnotation, "value"));
-    componentImplementation.registerModifiableModuleMethod(
-        moduleRequirement, method.getSimpleName().toString());
-  }
-
-  private void setConfigureInitializationMethod(
-      ComponentImplementation componentImplementation,
-      ExecutableElement method,
-      AnnotationMirror metadataAnnotation) {
-    ImmutableSet<ComponentRequirement> parameters =
-        asAnnotationValues(getAnnotationValue(metadataAnnotation, "value")).stream()
-            .map(this::parseComponentRequirement)
-            .collect(toImmutableSet());
-
-    componentImplementation.setConfigureInitializationMethod(
-        ConfigureInitializationMethod.create(MethodSpec.overriding(method).build(), parameters));
-  }
-
-  private void addChildImplementation(
-      ComponentDescriptor component,
-      ComponentImplementation componentImplementation,
-      TypeElement nestedType) {
-    getAnnotationMirror(nestedType, ComponentDefinitionType.class)
-        .transform(annotation -> (TypeMirror) getAnnotationValue(annotation, "value").getValue())
-        .transform(MoreTypes::asTypeElement)
-        .asSet()
-        .forEach(
-            componentDefinitionType -> {
-              ComponentDescriptor child =
-                  component.childComponentsByElement().get(componentDefinitionType);
-              componentImplementation.addChild(child, create(child, nestedType));
-            });
-  }
-
-  private Key parseKey(AnnotationValue annotationValue) {
-    return keyFactory.fromProto(
-        fromAnnotationValue(annotationValue, KeyProto.getDefaultInstance()));
-  }
-
-  private BindingRequest parseBindingRequest(AnnotationValue annotationValue) {
-    return fromProto(
-        fromAnnotationValue(annotationValue, BindingRequestProto.getDefaultInstance()));
-  }
-
-  private ComponentRequirement parseComponentRequirement(AnnotationValue annotationValue) {
-    return fromProto(
-        fromAnnotationValue(annotationValue, ComponentRequirementProto.getDefaultInstance()));
-  }
-
-  private ComponentRequirement fromProto(ComponentRequirementProto proto) {
-    switch (proto.getRequirementCase()) {
-      case MODULE:
-        return ComponentRequirement.forModule(typeProtoConverter.fromProto(proto.getModule()));
-      case DEPENDENCY:
-        return ComponentRequirement.forDependency(
-            typeProtoConverter.fromProto(proto.getDependency()));
-      case BOUND_INSTANCE:
-        return ComponentRequirement.forBoundInstance(
-            keyFactory.fromProto(proto.getBoundInstance().getKey()),
-            proto.getBoundInstance().getNullable(),
-            proto.getBoundInstance().getVariableName());
-      case REQUIREMENT_NOT_SET:
-        // fall through
-    }
-    throw new AssertionError(proto);
-  }
-}
diff --git a/java/dagger/internal/codegen/DiagnosticFormatting.java b/java/dagger/internal/codegen/DiagnosticFormatting.java
deleted file mode 100644
index 8502ecb..0000000
--- a/java/dagger/internal/codegen/DiagnosticFormatting.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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 java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Utility methods for formatting diagnostics to the {@link javax.annotation.processing.Messager}.
- */
-final class DiagnosticFormatting {
-
-  /**
-   * A regular expression to match a small list of specific packages deemed to be unhelpful to
-   * display in fully qualified types in error messages.
-   *
-   * <p>Note: This should never be applied to messages themselves.
-   */
-  private static final Pattern COMMON_PACKAGE_PATTERN =
-      Pattern.compile(
-          "(?:^|[^.a-z_])" // What we want to match on but not capture.
-              + "((?:" // Start a group with a non-capturing or part
-              + "java[.]lang"
-              + "|java[.]util"
-              + "|javax[.]inject"
-              + "|dagger"
-              + "|com[.]google[.]common[.]base"
-              + "|com[.]google[.]common[.]collect"
-              + ")[.])" // Always end with a literal .
-              + "[A-Z]"); // What we want to match on but not capture.
-
-  /**
-   * A method to strip out common packages and a few rare type prefixes from types' string
-   * representation before being used in error messages.
-   *
-   * <p>This type assumes a String value that is a valid fully qualified (and possibly
-   * parameterized) type, and should NOT be used with arbitrary text, especially prose error
-   * messages.
-   *
-   * <p>TODO(cgruber): Tighten these to take type representations (mirrors and elements) to avoid
-   * accidental mis-use by running errors through this method.
-   */
-  static String stripCommonTypePrefixes(String type) {
-    // Do regex magic to remove common packages we care to shorten.
-    Matcher matcher = COMMON_PACKAGE_PATTERN.matcher(type);
-    StringBuilder result = new StringBuilder();
-    int index = 0;
-    while (matcher.find()) {
-      result.append(type.subSequence(index, matcher.start(1)));
-      index = matcher.end(1); // Skip the matched pattern content.
-    }
-    result.append(type.subSequence(index, type.length()));
-    return result.toString();
-  }
-
-  private DiagnosticFormatting() {}
-}
diff --git a/java/dagger/internal/codegen/DiagnosticReporterFactory.java b/java/dagger/internal/codegen/DiagnosticReporterFactory.java
deleted file mode 100644
index f657cee..0000000
--- a/java/dagger/internal/codegen/DiagnosticReporterFactory.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2018 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.auto.common.MoreTypes.asTypeElement;
-import static com.google.common.base.Predicates.equalTo;
-import static com.google.common.base.Verify.verify;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.getLast;
-import static com.google.common.collect.Iterables.indexOf;
-import static com.google.common.collect.Iterables.transform;
-import static com.google.common.collect.Lists.asList;
-import static dagger.internal.codegen.DaggerGraphs.shortestPath;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.DaggerStreams.presentValues;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ElementFormatter.elementToString;
-import static dagger.internal.codegen.ValidationType.NONE;
-import static dagger.internal.codegen.langmodel.DaggerElements.DECLARATION_ORDER;
-import static dagger.internal.codegen.langmodel.DaggerElements.closestEnclosingTypeElement;
-import static dagger.internal.codegen.langmodel.DaggerElements.elementEncloses;
-import static java.util.Collections.min;
-import static java.util.Comparator.comparing;
-import static java.util.Comparator.comparingInt;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Table;
-import com.google.errorprone.annotations.FormatMethod;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ChildFactoryMethodEdge;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.Edge;
-import dagger.model.BindingGraph.MaybeBinding;
-import dagger.model.BindingGraph.Node;
-import dagger.model.ComponentPath;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.Comparator;
-import java.util.Set;
-import java.util.function.Function;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/** A factory for {@link DiagnosticReporter}s. */
-// TODO(ronshapiro): If multiple plugins print errors on the same node/edge, should we condense the
-// messages and only print the dependency trace once?
-final class DiagnosticReporterFactory {
-  private final DaggerTypes types;
-  private final Messager messager;
-  private final DependencyRequestFormatter dependencyRequestFormatter;
-  private final ElementFormatter elementFormatter;
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  DiagnosticReporterFactory(
-      DaggerTypes types,
-      Messager messager,
-      DependencyRequestFormatter dependencyRequestFormatter,
-      ElementFormatter elementFormatter,
-      CompilerOptions compilerOptions) {
-    this.types = types;
-    this.messager = messager;
-    this.dependencyRequestFormatter = dependencyRequestFormatter;
-    this.elementFormatter = elementFormatter;
-    this.compilerOptions = compilerOptions;
-  }
-
-  /** Creates a reporter for a binding graph and a plugin. */
-  DiagnosticReporterImpl reporter(BindingGraph graph, BindingGraphPlugin plugin) {
-    return new DiagnosticReporterImpl(graph, plugin.pluginName());
-  }
-
-  private static <K, V> Function<K, V> memoize(Function<K, V> uncached) {
-    // If Android Guava is on the processor path, then c.g.c.b.Function (which LoadingCache
-    // implements) does not extend j.u.f.Function.
-
-    // First, explicitly convert uncached to c.g.c.b.Function because CacheLoader.from() expects
-    // one.
-    com.google.common.base.Function<K, V> uncachedAsBaseFunction = uncached::apply;
-
-    LoadingCache<K, V> cache =
-        CacheBuilder.newBuilder().build(CacheLoader.from(uncachedAsBaseFunction));
-
-    // Second, explicitly convert LoadingCache to j.u.f.Function.
-    @SuppressWarnings("deprecation") // uncachedAsBaseFunction throws only unchecked exceptions
-    Function<K, V> memoized = cache::apply;
-
-    return memoized;
-  }
-
-  /**
-   * A {@link DiagnosticReporter} that keeps track of which {@linkplain Diagnostic.Kind kinds} of
-   * diagnostics were reported.
-   */
-  final class DiagnosticReporterImpl implements DiagnosticReporter {
-
-    /** A cached function from type to all of its supertypes in breadth-first order. */
-    private final Function<TypeElement, Iterable<TypeElement>> supertypes =
-        memoize(
-            component ->
-                transform(types.supertypes(component.asType()), type -> asTypeElement(type)));
-
-    /** The shortest path (value) from an entry point (column) to a binding (row). */
-    private final Table<MaybeBinding, DependencyEdge, ImmutableList<Node>> shortestPaths =
-        HashBasedTable.create();
-
-    private final BindingGraph graph;
-    private final String plugin;
-    private final TypeElement rootComponent;
-    private final ImmutableSet.Builder<Diagnostic.Kind> reportedDiagnosticKinds =
-        ImmutableSet.builder();
-
-    DiagnosticReporterImpl(BindingGraph graph, String plugin) {
-      this.graph = graph;
-      this.plugin = plugin;
-      this.rootComponent = graph.rootComponentNode().componentPath().currentComponent();
-    }
-
-    /** Returns which {@linkplain Diagnostic.Kind kinds} of diagnostics were reported. */
-    ImmutableSet<Diagnostic.Kind> reportedDiagnosticKinds() {
-      return reportedDiagnosticKinds.build();
-    }
-
-    @Override
-    public void reportComponent(
-        Diagnostic.Kind diagnosticKind, ComponentNode componentNode, String messageFormat) {
-      StringBuilder message = new StringBuilder(messageFormat);
-      appendComponentPathUnlessAtRoot(message, componentNode);
-      // TODO(dpb): Report at the component node component.
-      printMessage(diagnosticKind, message, rootComponent);
-    }
-
-    @Override
-    @FormatMethod
-    public void reportComponent(
-        Diagnostic.Kind diagnosticKind,
-        ComponentNode componentNode,
-        String messageFormat,
-        Object firstArg,
-        Object... moreArgs) {
-      reportComponent(
-          diagnosticKind, componentNode, formatMessage(messageFormat, firstArg, moreArgs));
-    }
-
-    // TODO(ronshapiro): should this also include the binding element?
-    @Override
-    public void reportBinding(
-        Diagnostic.Kind diagnosticKind, MaybeBinding binding, String message) {
-      printMessage(diagnosticKind, message + new DiagnosticInfo(binding), rootComponent);
-    }
-
-    @Override
-    public void reportBinding(
-        Diagnostic.Kind diagnosticKind,
-        MaybeBinding binding,
-        String messageFormat,
-        Object firstArg,
-        Object... moreArgs) {
-      reportBinding(diagnosticKind, binding, formatMessage(messageFormat, firstArg, moreArgs));
-    }
-
-    @Override
-    public void reportDependency(
-        Diagnostic.Kind diagnosticKind, DependencyEdge dependencyEdge, String message) {
-      printMessage(diagnosticKind, message + new DiagnosticInfo(dependencyEdge), rootComponent);
-    }
-
-    @Override
-    public void reportDependency(
-        Diagnostic.Kind diagnosticKind,
-        DependencyEdge dependencyEdge,
-        String messageFormat,
-        Object firstArg,
-        Object... moreArgs) {
-      reportDependency(
-          diagnosticKind, dependencyEdge, formatMessage(messageFormat, firstArg, moreArgs));
-    }
-
-    @Override
-    public void reportSubcomponentFactoryMethod(
-        Diagnostic.Kind diagnosticKind,
-        ChildFactoryMethodEdge childFactoryMethodEdge,
-        String message) {
-      printMessage(diagnosticKind, message, childFactoryMethodEdge.factoryMethod());
-    }
-
-    @Override
-    public void reportSubcomponentFactoryMethod(
-        Diagnostic.Kind diagnosticKind,
-        ChildFactoryMethodEdge childFactoryMethodEdge,
-        String messageFormat,
-        Object firstArg,
-        Object... moreArgs) {
-      reportSubcomponentFactoryMethod(
-          diagnosticKind, childFactoryMethodEdge, formatMessage(messageFormat, firstArg, moreArgs));
-    }
-
-    private String formatMessage(String messageFormat, Object firstArg, Object[] moreArgs) {
-      return String.format(messageFormat, asList(firstArg, moreArgs).toArray());
-    }
-
-    private Node source(Edge edge) {
-      return graph.network().incidentNodes(edge).source();
-    }
-
-    void printMessage(
-        Diagnostic.Kind diagnosticKind,
-        CharSequence message,
-        @NullableDecl Element elementToReport) {
-      if (graph.isFullBindingGraph()) {
-        ValidationType validationType =
-            compilerOptions.fullBindingGraphValidationType(rootComponent);
-        if (validationType.equals(NONE)) {
-          return;
-        }
-        if (diagnosticKind.equals(ERROR)) {
-          diagnosticKind = validationType.diagnosticKind().get();
-        }
-      }
-      reportedDiagnosticKinds.add(diagnosticKind);
-      StringBuilder fullMessage = new StringBuilder();
-      appendBracketPrefix(fullMessage, plugin);
-
-      // TODO(ronshapiro): should we create a HashSet out of elementEncloses() so we don't
-      // need to do an O(n) contains() each time?
-      if (elementToReport != null && !elementEncloses(rootComponent, elementToReport)) {
-        appendBracketPrefix(fullMessage, elementToString(elementToReport));
-        elementToReport = rootComponent;
-      }
-
-      messager.printMessage(diagnosticKind, fullMessage.append(message), elementToReport);
-    }
-
-    private void appendComponentPathUnlessAtRoot(StringBuilder message, Node node) {
-      if (!node.componentPath().equals(graph.rootComponentNode().componentPath())) {
-        message.append(String.format(" [%s]", node.componentPath()));
-      }
-    }
-
-    private void appendBracketPrefix(StringBuilder message, String prefix) {
-      message.append(String.format("[%s] ", prefix));
-    }
-
-    /** The diagnostic information associated with an error. */
-    private final class DiagnosticInfo {
-      final ImmutableList<DependencyEdge> dependencyTrace;
-      final ImmutableSet<DependencyEdge> requests;
-      final ImmutableSet<DependencyEdge> entryPoints;
-
-      DiagnosticInfo(MaybeBinding binding) {
-        entryPoints = graph.entryPointEdgesDependingOnBinding(binding);
-        requests = requests(binding);
-        dependencyTrace = dependencyTrace(binding, entryPoints);
-      }
-
-      DiagnosticInfo(DependencyEdge dependencyEdge) {
-        requests = ImmutableSet.of(dependencyEdge);
-        ImmutableList.Builder<DependencyEdge> dependencyTraceBuilder = ImmutableList.builder();
-        dependencyTraceBuilder.add(dependencyEdge);
-
-        if (dependencyEdge.isEntryPoint()) {
-          entryPoints = ImmutableSet.of(dependencyEdge);
-        } else {
-          // It's not an entry point, so it's part of a binding
-          dagger.model.Binding binding = (dagger.model.Binding) source(dependencyEdge);
-          entryPoints = graph.entryPointEdgesDependingOnBinding(binding);
-          dependencyTraceBuilder.addAll(dependencyTrace(binding, entryPoints));
-        }
-        dependencyTrace = dependencyTraceBuilder.build();
-      }
-
-      @Override
-      public String toString() {
-        StringBuilder message =
-            graph.isFullBindingGraph()
-                ? new StringBuilder()
-                : new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */);
-
-        // Print the dependency trace unless it's a full binding graph
-        if (!graph.isFullBindingGraph()) {
-          dependencyTrace.forEach(
-              edge ->
-                  dependencyRequestFormatter.appendFormatLine(message, edge.dependencyRequest()));
-          if (!dependencyTrace.isEmpty()) {
-            appendComponentPathUnlessAtRoot(message, source(getLast(dependencyTrace)));
-          }
-        }
-
-        // Print any dependency requests that aren't shown as part of the dependency trace.
-        ImmutableSet<Element> requestsToPrint =
-            requests.stream()
-                // if printing entry points, skip entry points and the traced request
-                .filter(
-                    request ->
-                        graph.isFullBindingGraph()
-                            || (!request.isEntryPoint() && !isTracedRequest(request)))
-                .map(request -> request.dependencyRequest().requestElement())
-                .flatMap(presentValues())
-                .collect(toImmutableSet());
-        if (!requestsToPrint.isEmpty()) {
-          message
-              .append("\nIt is")
-              .append(graph.isFullBindingGraph() ? " " : " also ")
-              .append("requested at:");
-          elementFormatter.formatIndentedList(message, requestsToPrint, 1);
-        }
-
-        // Print the remaining entry points, showing which component they're in, unless it's a full
-        // binding graph
-        if (!graph.isFullBindingGraph() && entryPoints.size() > 1) {
-          message.append("\nThe following other entry points also depend on it:");
-          entryPointFormatter.formatIndentedList(
-              message,
-              entryPoints.stream()
-                  .filter(entryPoint -> !entryPoint.equals(getLast(dependencyTrace)))
-                  .sorted(
-                      // 1. List entry points in components closest to the root first.
-                      // 2. List entry points declared in a component before those in a supertype.
-                      // 3. List entry points in declaration order in their declaring type.
-                      rootComponentFirst()
-                          .thenComparing(nearestComponentSupertypeFirst())
-                          .thenComparing(requestElementDeclarationOrder()))
-                  .collect(toImmutableList()),
-              1);
-        }
-        return message.toString();
-      }
-
-      private final Formatter<DependencyEdge> entryPointFormatter =
-          new Formatter<DependencyEdge>() {
-            @Override
-            public String format(DependencyEdge object) {
-              Element requestElement = object.dependencyRequest().requestElement().get();
-              StringBuilder element = new StringBuilder(elementToString(requestElement));
-
-              // For entry points declared in subcomponents or supertypes of the root component,
-              // append the component path to make clear to the user which component it's in.
-              ComponentPath componentPath = source(object).componentPath();
-              if (!componentPath.atRoot()
-                  || !requestElement.getEnclosingElement().equals(rootComponent)) {
-                element.append(String.format(" [%s]", componentPath));
-              }
-              return element.toString();
-            }
-          };
-
-      private boolean isTracedRequest(DependencyEdge request) {
-        return !dependencyTrace.isEmpty() && request.equals(dependencyTrace.get(0));
-      }
-
-      /**
-       * Returns the dependency trace from one of the {@code entryPoints} to {@code binding} to
-       * {@code message} as a list <i>ending with</i> the entry point.
-       */
-      // TODO(ronshapiro): Adding a DependencyPath type to dagger.model could be useful, i.e.
-      // bindingGraph.shortestPathFromEntryPoint(DependencyEdge, MaybeBindingNode)
-      ImmutableList<DependencyEdge> dependencyTrace(
-          MaybeBinding binding, ImmutableSet<DependencyEdge> entryPoints) {
-        // Module binding graphs may have bindings unreachable from any entry points. If there are
-        // no entry points for this DiagnosticInfo, don't try to print a dependency trace.
-        if (entryPoints.isEmpty()) {
-          return ImmutableList.of();
-        }
-        // Show the full dependency trace for one entry point.
-        DependencyEdge entryPointForTrace =
-            min(
-                entryPoints,
-                // prefer entry points in components closest to the root
-                rootComponentFirst()
-                    // then prefer entry points with a short dependency path to the error
-                    .thenComparing(shortestDependencyPathFirst(binding))
-                    // then prefer entry points declared in the component to those declared in a
-                    // supertype
-                    .thenComparing(nearestComponentSupertypeFirst())
-                    // finally prefer entry points declared first in their enclosing type
-                    .thenComparing(requestElementDeclarationOrder()));
-
-        ImmutableList<Node> shortestBindingPath =
-            shortestPathFromEntryPoint(entryPointForTrace, binding);
-        verify(
-            !shortestBindingPath.isEmpty(),
-            "no dependency path from %s to %s in %s",
-            entryPointForTrace,
-            binding,
-            graph);
-
-        ImmutableList.Builder<DependencyEdge> dependencyTrace = ImmutableList.builder();
-        dependencyTrace.add(entryPointForTrace);
-        for (int i = 0; i < shortestBindingPath.size() - 1; i++) {
-          Set<Edge> dependenciesBetween =
-              graph
-                  .network()
-                  .edgesConnecting(shortestBindingPath.get(i), shortestBindingPath.get(i + 1));
-          // If a binding requests a key more than once, any of them should be fine to get to the
-          // shortest path
-          dependencyTrace.add((DependencyEdge) Iterables.get(dependenciesBetween, 0));
-        }
-        return dependencyTrace.build().reverse();
-      }
-
-      /** Returns all the nonsynthetic dependency requests for a binding. */
-      ImmutableSet<DependencyEdge> requests(MaybeBinding binding) {
-        return graph.network().inEdges(binding).stream()
-            .flatMap(instancesOf(DependencyEdge.class))
-            .filter(edge -> edge.dependencyRequest().requestElement().isPresent())
-            .sorted(requestEnclosingTypeName().thenComparing(requestElementDeclarationOrder()))
-            .collect(toImmutableSet());
-      }
-
-      /**
-       * Returns a comparator that sorts entry points in components whose paths from the root are
-       * shorter first.
-       */
-      Comparator<DependencyEdge> rootComponentFirst() {
-        return comparingInt(entryPoint -> source(entryPoint).componentPath().components().size());
-      }
-
-      /**
-       * Returns a comparator that puts entry points whose shortest dependency path to {@code
-       * binding} is shortest first.
-       */
-      Comparator<DependencyEdge> shortestDependencyPathFirst(MaybeBinding binding) {
-        return comparing(entryPoint -> shortestPathFromEntryPoint(entryPoint, binding).size());
-      }
-
-      ImmutableList<Node> shortestPathFromEntryPoint(
-          DependencyEdge entryPoint, MaybeBinding binding) {
-        return shortestPaths
-            .row(binding)
-            .computeIfAbsent(
-                entryPoint,
-                ep ->
-                    shortestPath(
-                        node ->
-                            filter(
-                                graph.network().successors(node), MaybeBinding.class::isInstance),
-                        graph.network().incidentNodes(ep).target(),
-                        binding));
-      }
-
-      /**
-       * Returns a comparator that sorts entry points in by the distance of the type that declares
-       * them from the type of the component that contains them.
-       *
-       * <p>For instance, an entry point declared directly in the component type would sort before
-       * one declared in a direct supertype, which would sort before one declared in a supertype of
-       * a supertype.
-       */
-      Comparator<DependencyEdge> nearestComponentSupertypeFirst() {
-        return comparingInt(
-            entryPoint ->
-                indexOf(
-                    supertypes.apply(componentContainingEntryPoint(entryPoint)),
-                    equalTo(typeDeclaringEntryPoint(entryPoint))));
-      }
-
-      TypeElement componentContainingEntryPoint(DependencyEdge entryPoint) {
-        return source(entryPoint).componentPath().currentComponent();
-      }
-
-      TypeElement typeDeclaringEntryPoint(DependencyEdge entryPoint) {
-        return MoreElements.asType(
-            entryPoint.dependencyRequest().requestElement().get().getEnclosingElement());
-      }
-
-      /**
-       * Returns a comparator that sorts dependency edges lexicographically by the qualified name of
-       * the type that contains them. Only appropriate for edges with request elements.
-       */
-      Comparator<DependencyEdge> requestEnclosingTypeName() {
-        return comparing(
-            edge ->
-                closestEnclosingTypeElement(edge.dependencyRequest().requestElement().get())
-                    .getQualifiedName()
-                    .toString());
-      }
-
-      /**
-       * Returns a comparator that sorts edges in the order in which their request elements were
-       * declared in their declaring type.
-       *
-       * <p>Only useful to compare edges whose request elements were declared in the same type.
-       */
-      Comparator<DependencyEdge> requestElementDeclarationOrder() {
-        return comparing(
-            edge -> edge.dependencyRequest().requestElement().get(), DECLARATION_ORDER);
-      }
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/DuplicateBindingsValidator.java b/java/dagger/internal/codegen/DuplicateBindingsValidator.java
deleted file mode 100644
index 3eed45f..0000000
--- a/java/dagger/internal/codegen/DuplicateBindingsValidator.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2018 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.Verify.verify;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSetMultimap;
-import static dagger.internal.codegen.Formatter.INDENT;
-import static dagger.internal.codegen.Optionals.emptiesLast;
-import static dagger.model.BindingKind.INJECTION;
-import static dagger.model.BindingKind.MEMBERS_INJECTION;
-import static java.util.Comparator.comparing;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Sets;
-import dagger.model.Binding;
-import dagger.model.BindingGraph;
-import dagger.model.BindingKind;
-import dagger.model.ComponentPath;
-import dagger.model.Key;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Predicate;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic.Kind;
-
-/** Reports errors for conflicting bindings with the same key. */
-final class DuplicateBindingsValidator implements BindingGraphPlugin {
-
-  // 1. contributing module or enclosing type
-  // 2. binding element's simple name
-  // 3. binding element's type
-  private static final Comparator<BindingDeclaration> BINDING_DECLARATION_COMPARATOR =
-      comparing(
-              (BindingDeclaration declaration) ->
-                  declaration.contributingModule().isPresent()
-                      ? declaration.contributingModule()
-                      : declaration.bindingTypeElement(),
-              emptiesLast(comparing((TypeElement type) -> type.getQualifiedName().toString())))
-          .thenComparing(
-              (BindingDeclaration declaration) -> declaration.bindingElement(),
-              emptiesLast(
-                  comparing((Element element) -> element.getSimpleName().toString())
-                      .thenComparing((Element element) -> element.asType().toString())));
-
-  private static final Comparator<Binding> BY_LENGTH_OF_COMPONENT_PATH =
-      comparing(binding -> binding.componentPath().components().size());
-
-  private final BindingDeclarationFormatter bindingDeclarationFormatter;
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  DuplicateBindingsValidator(
-      BindingDeclarationFormatter bindingDeclarationFormatter, CompilerOptions compilerOptions) {
-    this.bindingDeclarationFormatter = bindingDeclarationFormatter;
-    this.compilerOptions = compilerOptions;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/DuplicateBindings";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    // If two unrelated subcomponents have the same duplicate bindings only because they install the
-    // same two modules, then fixing the error in one subcomponent will uncover the second
-    // subcomponent to fix.
-    // TODO(ronshapiro): Explore ways to address such underreporting without overreporting.
-    Set<ImmutableSet<BindingElement>> reportedDuplicateBindingSets = new HashSet<>();
-    duplicateBindingSets(bindingGraph)
-        .forEach(
-            duplicateBindings -> {
-              // Only report each set of duplicate bindings once, ignoring the installed component.
-              if (reportedDuplicateBindingSets.add(duplicateBindings.keySet())) {
-                reportDuplicateBindings(duplicateBindings, bindingGraph, diagnosticReporter);
-              }
-            });
-  }
-
-  /**
-   * Returns sets of duplicate bindings. Bindings are duplicates if they bind the same key and are
-   * visible from the same component. Two bindings that differ only in the component that owns them
-   * are not considered to be duplicates, because that means the same binding was "copied" down to a
-   * descendant component because it depends on local multibindings or optional bindings. Hence each
-   * "set" is represented as a multimap from binding element (ignoring component path) to binding.
-   */
-  private ImmutableSet<ImmutableSetMultimap<BindingElement, Binding>> duplicateBindingSets(
-      BindingGraph bindingGraph) {
-    return groupBindingsByKey(bindingGraph).stream()
-        .flatMap(bindings -> mutuallyVisibleSubsets(bindings).stream())
-        .map(BindingElement::index)
-        .filter(duplicates -> duplicates.keySet().size() > 1)
-        .collect(toImmutableSet());
-  }
-
-  private static ImmutableSet<ImmutableSet<Binding>> groupBindingsByKey(BindingGraph bindingGraph) {
-    return valueSetsForEachKey(
-        bindingGraph.bindings().stream()
-            .filter(binding -> !binding.kind().equals(MEMBERS_INJECTION))
-            .collect(toImmutableSetMultimap(Binding::key, binding -> binding)));
-  }
-
-  /**
-   * Returns the subsets of the input set that contain bindings that are all visible from the same
-   * component. A binding is visible from its component and all its descendants.
-   */
-  private static ImmutableSet<ImmutableSet<Binding>> mutuallyVisibleSubsets(
-      Set<Binding> duplicateBindings) {
-    ImmutableListMultimap<ComponentPath, Binding> bindingsByComponentPath =
-        Multimaps.index(duplicateBindings, Binding::componentPath);
-    ImmutableSetMultimap.Builder<ComponentPath, Binding> mutuallyVisibleBindings =
-        ImmutableSetMultimap.builder();
-    bindingsByComponentPath
-        .asMap()
-        .forEach(
-            (componentPath, bindings) -> {
-              mutuallyVisibleBindings.putAll(componentPath, bindings);
-              for (ComponentPath ancestor = componentPath; !ancestor.atRoot(); ) {
-                ancestor = ancestor.parent();
-                ImmutableList<Binding> bindingsInAncestor = bindingsByComponentPath.get(ancestor);
-                mutuallyVisibleBindings.putAll(componentPath, bindingsInAncestor);
-              }
-            });
-    return valueSetsForEachKey(mutuallyVisibleBindings.build());
-  }
-
-  private void reportDuplicateBindings(
-      ImmutableSetMultimap<BindingElement, Binding> duplicateBindings,
-      BindingGraph bindingGraph,
-      DiagnosticReporter diagnosticReporter) {
-    if (explicitBindingConfictsWithInject(duplicateBindings.keySet())) {
-      compilerOptions
-          .explicitBindingConflictsWithInjectValidationType()
-          .diagnosticKind()
-          .ifPresent(
-              diagnosticKind ->
-                  reportExplicitBindingConflictsWithInject(
-                      duplicateBindings, diagnosticReporter, diagnosticKind));
-      return;
-    }
-    ImmutableSet<Binding> bindings = ImmutableSet.copyOf(duplicateBindings.values());
-    Binding oneBinding = bindings.asList().get(0);
-    diagnosticReporter.reportBinding(
-        ERROR,
-        oneBinding,
-        Iterables.any(bindings, binding -> binding.kind().isMultibinding())
-            ? incompatibleBindingsMessage(oneBinding.key(), bindings, bindingGraph)
-            : duplicateBindingMessage(oneBinding.key(), bindings, bindingGraph));
-  }
-
-  /**
-   * Returns {@code true} if the bindings contain one {@code @Inject} binding and one that isn't.
-   */
-  private static boolean explicitBindingConfictsWithInject(
-      ImmutableSet<BindingElement> duplicateBindings) {
-    ImmutableMultiset<BindingKind> bindingKinds =
-        Multimaps.index(duplicateBindings, BindingElement::bindingKind).keys();
-    return bindingKinds.count(INJECTION) == 1 && bindingKinds.size() == 2;
-  }
-
-  private void reportExplicitBindingConflictsWithInject(
-      ImmutableSetMultimap<BindingElement, Binding> duplicateBindings,
-      DiagnosticReporter diagnosticReporter,
-      Kind diagnosticKind) {
-    Binding injectBinding =
-        rootmostBindingWithKind(k -> k.equals(INJECTION), duplicateBindings.values());
-    Binding explicitBinding =
-        rootmostBindingWithKind(k -> !k.equals(INJECTION), duplicateBindings.values());
-    StringBuilder message =
-        new StringBuilder()
-            .append(explicitBinding.key())
-            .append(" is bound multiple times:")
-            .append(formatWithComponentPath(injectBinding))
-            .append(formatWithComponentPath(explicitBinding))
-            .append(
-                "\nThis condition was never validated before, and will soon be an error. "
-                    + "See https://dagger.dev/conflicting-inject.");
-
-    diagnosticReporter.reportBinding(diagnosticKind, explicitBinding, message.toString());
-  }
-
-  private String formatWithComponentPath(Binding binding) {
-    return String.format(
-        "\n%s%s [%s]",
-        Formatter.INDENT,
-        bindingDeclarationFormatter.format(((BindingNode) binding).delegate()),
-        binding.componentPath());
-  }
-
-  private String duplicateBindingMessage(
-      Key key, ImmutableSet<Binding> duplicateBindings, BindingGraph graph) {
-    StringBuilder message = new StringBuilder().append(key).append(" is bound multiple times:");
-    formatDeclarations(message, 1, declarations(graph, duplicateBindings));
-    return message.toString();
-  }
-
-  private String incompatibleBindingsMessage(
-      Key key, ImmutableSet<Binding> duplicateBindings, BindingGraph graph) {
-    ImmutableSet<dagger.model.Binding> multibindings =
-        duplicateBindings.stream()
-            .filter(binding -> binding.kind().isMultibinding())
-            .collect(toImmutableSet());
-    verify(
-        multibindings.size() == 1, "expected only one multibinding for %s: %s", key, multibindings);
-    StringBuilder message = new StringBuilder();
-    java.util.Formatter messageFormatter = new java.util.Formatter(message);
-    messageFormatter.format("%s has incompatible bindings or declarations:\n", key);
-    message.append(INDENT);
-    dagger.model.Binding multibinding = getOnlyElement(multibindings);
-    messageFormatter.format("%s bindings and declarations:", multibindingTypeString(multibinding));
-    formatDeclarations(message, 2, declarations(graph, multibindings));
-
-    Set<dagger.model.Binding> uniqueBindings =
-        Sets.filter(duplicateBindings, binding -> !binding.equals(multibinding));
-    message.append('\n').append(INDENT).append("Unique bindings and declarations:");
-    formatDeclarations(
-        message,
-        2,
-        Sets.filter(
-            declarations(graph, uniqueBindings),
-            declaration -> !(declaration instanceof MultibindingDeclaration)));
-    return message.toString();
-  }
-
-  private void formatDeclarations(
-      StringBuilder builder,
-      int indentLevel,
-      Iterable<? extends BindingDeclaration> bindingDeclarations) {
-    bindingDeclarationFormatter.formatIndentedList(
-        builder, ImmutableList.copyOf(bindingDeclarations), indentLevel);
-  }
-
-  private ImmutableSet<BindingDeclaration> declarations(
-      BindingGraph graph, Set<dagger.model.Binding> bindings) {
-    return bindings.stream()
-        .flatMap(binding -> declarations(graph, binding).stream())
-        .distinct()
-        .sorted(BINDING_DECLARATION_COMPARATOR)
-        .collect(toImmutableSet());
-  }
-
-  private ImmutableSet<BindingDeclaration> declarations(
-      BindingGraph graph, dagger.model.Binding binding) {
-    ImmutableSet.Builder<BindingDeclaration> declarations = ImmutableSet.builder();
-    BindingNode bindingNode = (BindingNode) binding;
-    bindingNode.associatedDeclarations().forEach(declarations::add);
-    if (bindingDeclarationFormatter.canFormat(bindingNode.delegate())) {
-      declarations.add(bindingNode.delegate());
-    } else {
-      graph.requestedBindings(binding).stream()
-          .flatMap(requestedBinding -> declarations(graph, requestedBinding).stream())
-          .forEach(declarations::add);
-    }
-    return declarations.build();
-  }
-
-  private String multibindingTypeString(dagger.model.Binding multibinding) {
-    switch (multibinding.kind()) {
-      case MULTIBOUND_MAP:
-        return "Map";
-      case MULTIBOUND_SET:
-        return "Set";
-      default:
-        throw new AssertionError(multibinding);
-    }
-  }
-
-  private static <E> ImmutableSet<ImmutableSet<E>> valueSetsForEachKey(Multimap<?, E> multimap) {
-    return multimap.asMap().values().stream().map(ImmutableSet::copyOf).collect(toImmutableSet());
-  }
-
-  /** Returns the binding of the given kind that is closest to the root component. */
-  private static Binding rootmostBindingWithKind(
-      Predicate<BindingKind> bindingKindPredicate, ImmutableCollection<Binding> bindings) {
-    return bindings.stream()
-        .filter(b -> bindingKindPredicate.test(b.kind()))
-        .min(BY_LENGTH_OF_COMPONENT_PATH)
-        .get();
-  }
-
-  /** The identifying information about a binding, excluding its {@link Binding#componentPath()}. */
-  @AutoValue
-  abstract static class BindingElement {
-
-    abstract BindingKind bindingKind();
-
-    abstract Optional<Element> bindingElement();
-
-    abstract Optional<TypeElement> contributingModule();
-
-    static ImmutableSetMultimap<BindingElement, Binding> index(Set<Binding> bindings) {
-      return bindings.stream().collect(toImmutableSetMultimap(BindingElement::forBinding, b -> b));
-    }
-
-    private static BindingElement forBinding(Binding binding) {
-      return new AutoValue_DuplicateBindingsValidator_BindingElement(
-          binding.kind(), binding.bindingElement(), binding.contributingModule());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ElementFormatter.java b/java/dagger/internal/codegen/ElementFormatter.java
deleted file mode 100644
index 40d7606..0000000
--- a/java/dagger/internal/codegen/ElementFormatter.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 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.auto.common.MoreElements.asExecutable;
-import static java.util.stream.Collectors.joining;
-
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.ElementKindVisitor8;
-
-/**
- * Formats elements into a useful string representation.
- *
- * <p>Elements directly enclosed by a type are preceded by the enclosing type's qualified name.
- *
- * <p>Parameters are given with their enclosing executable, with other parameters elided.
- */
-final class ElementFormatter extends Formatter<Element> {
-  @Inject
-  ElementFormatter() {}
-
-  @Override
-  public String format(Element element) {
-    return elementToString(element);
-  }
-
-  /**
-   * Returns a useful string form for an element.
-   *
-   * <p>Elements directly enclosed by a type are preceded by the enclosing type's qualified name.
-   *
-   * <p>Parameters are given with their enclosing executable, with other parameters elided.
-   */
-  static String elementToString(Element element) {
-    return element.accept(ELEMENT_TO_STRING, null);
-  }
-
-  private static final ElementVisitor<String, Void> ELEMENT_TO_STRING =
-      new ElementKindVisitor8<String, Void>() {
-        @Override
-        public String visitExecutable(ExecutableElement executableElement, Void aVoid) {
-          return enclosingTypeAndMemberName(executableElement)
-              .append(
-                  executableElement.getParameters().stream()
-                      .map(parameter -> parameter.asType().toString())
-                      .collect(joining(", ", "(", ")")))
-              .toString();
-        }
-
-        @Override
-        public String visitVariableAsParameter(VariableElement parameter, Void aVoid) {
-          ExecutableElement methodOrConstructor = asExecutable(parameter.getEnclosingElement());
-          return enclosingTypeAndMemberName(methodOrConstructor)
-              .append('(')
-              .append(
-                  formatArgumentInList(
-                      methodOrConstructor.getParameters().indexOf(parameter),
-                      methodOrConstructor.getParameters().size(),
-                      parameter.getSimpleName()))
-              .append(')')
-              .toString();
-        }
-
-        @Override
-        public String visitVariableAsField(VariableElement field, Void aVoid) {
-          return enclosingTypeAndMemberName(field).toString();
-        }
-
-        @Override
-        public String visitType(TypeElement type, Void aVoid) {
-          return type.getQualifiedName().toString();
-        }
-
-        @Override
-        protected String defaultAction(Element element, Void aVoid) {
-          throw new UnsupportedOperationException(
-              "Can't determine string for " + element.getKind() + " element " + element);
-        }
-
-        private StringBuilder enclosingTypeAndMemberName(Element element) {
-          StringBuilder name = new StringBuilder(element.getEnclosingElement().accept(this, null));
-          if (!element.getSimpleName().contentEquals("<init>")) {
-            name.append('.').append(element.getSimpleName());
-          }
-          return name;
-        }
-      };
-}
diff --git a/java/dagger/internal/codegen/ErrorMessages.java b/java/dagger/internal/codegen/ErrorMessages.java
deleted file mode 100644
index 4195e1a..0000000
--- a/java/dagger/internal/codegen/ErrorMessages.java
+++ /dev/null
@@ -1,356 +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 com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableMap;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.function.UnaryOperator;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/** The collection of error messages to be reported back to users. */
-final class ErrorMessages {
-
-  private static final UnaryOperator<String> PRODUCTION =
-      s ->
-          s.replace("component", "production component")
-              .replace("Component", "ProductionComponent");
-
-  private static final UnaryOperator<String> SUBCOMPONENT =
-      s -> s.replace("component", "subcomponent").replace("Component", "Subcomponent");
-
-  private static final UnaryOperator<String> FACTORY = s -> s.replace("Builder", "Factory");
-
-  private static final ImmutableMap<ComponentKind, Function<String, String>>
-      COMPONENT_TRANSFORMATIONS =
-          ImmutableMap.of(
-              ComponentKind.COMPONENT, UnaryOperator.identity(),
-              ComponentKind.SUBCOMPONENT, SUBCOMPONENT,
-              ComponentKind.PRODUCTION_COMPONENT, PRODUCTION,
-              ComponentKind.PRODUCTION_SUBCOMPONENT, PRODUCTION.andThen(SUBCOMPONENT));
-
-  static ComponentMessages componentMessagesFor(ComponentKind componentKind) {
-    return new ComponentMessages(COMPONENT_TRANSFORMATIONS.get(componentKind));
-  }
-
-  static ComponentMessages componentMessagesFor(ComponentAnnotation componentAnnotation) {
-    return new ComponentMessages(
-        transformation(componentAnnotation.isProduction(), componentAnnotation.isSubcomponent()));
-  }
-
-  static ComponentCreatorMessages creatorMessagesFor(ComponentCreatorAnnotation creatorAnnotation) {
-    Function<String, String> transformation =
-        transformation(
-            creatorAnnotation.isProductionCreatorAnnotation(),
-            creatorAnnotation.isSubcomponentCreatorAnnotation());
-    switch (creatorAnnotation.creatorKind()) {
-      case BUILDER:
-        return new BuilderMessages(transformation);
-      case FACTORY:
-        return new FactoryMessages(transformation);
-    }
-    throw new AssertionError(creatorAnnotation);
-  }
-
-  private static Function<String, String> transformation(
-      boolean isProduction, boolean isSubcomponent) {
-    Function<String, String> transformation = isProduction ? PRODUCTION : UnaryOperator.identity();
-    return isSubcomponent ? transformation.andThen(SUBCOMPONENT) : transformation;
-  }
-
-  private abstract static class Messages {
-    private final Function<String, String> transformation;
-
-    Messages(Function<String, String> transformation) {
-      this.transformation = transformation;
-    }
-
-    protected final String process(String s) {
-      return transformation.apply(s);
-    }
-  }
-
-  /** Errors for components. */
-  static final class ComponentMessages extends Messages {
-    ComponentMessages(Function<String, String> transformation) {
-      super(transformation);
-    }
-
-    final String moreThanOne() {
-      return process("@Component has more than one @Component.Builder or @Component.Factory: %s");
-    }
-  }
-
-  /** Errors for component creators. */
-  abstract static class ComponentCreatorMessages extends Messages {
-    ComponentCreatorMessages(Function<String, String> transformation) {
-      super(transformation);
-    }
-
-    static String builderMethodRequiresNoArgs() {
-      return "Methods returning a @Component.Builder must have no arguments";
-    }
-
-    static String moreThanOneRefToSubcomponent() {
-      return "Only one method can create a given subcomponent. %s is created by: %s";
-    }
-
-    final String invalidConstructor() {
-      return process("@Component.Builder classes must have exactly one constructor,"
-          + " and it must not be private or have any parameters");
-    }
-
-    final String generics() {
-      return process("@Component.Builder types must not have any generic types");
-    }
-
-    final String mustBeInComponent() {
-      return process("@Component.Builder types must be nested within a @Component");
-    }
-
-    final String mustBeClassOrInterface() {
-      return process("@Component.Builder types must be abstract classes or interfaces");
-    }
-
-    final String isPrivate() {
-      return process("@Component.Builder types must not be private");
-    }
-
-    final String mustBeStatic() {
-      return process("@Component.Builder types must be static");
-    }
-
-    final String mustBeAbstract() {
-      return process("@Component.Builder types must be abstract");
-    }
-
-    abstract String missingFactoryMethod();
-
-    abstract String multipleSettersForModuleOrDependencyType();
-
-    abstract String extraSetters();
-
-    abstract String missingSetters();
-
-    abstract String twoFactoryMethods();
-
-    abstract String inheritedTwoFactoryMethods();
-
-    abstract String factoryMethodMustReturnComponentType();
-
-    final String inheritedFactoryMethodMustReturnComponentType() {
-      return factoryMethodMustReturnComponentType() + ". Inherited method: %s";
-    }
-
-    abstract String factoryMethodMayNotBeAnnotatedWithBindsInstance();
-
-    final String inheritedFactoryMethodMayNotBeAnnotatedWithBindsInstance() {
-      return factoryMethodMayNotBeAnnotatedWithBindsInstance() + ". Inherited method: %s";
-    }
-
-    final String setterMethodsMustTakeOneArg() {
-      return process("@Component.Builder methods must not have more than one argument");
-    }
-
-    final String inheritedSetterMethodsMustTakeOneArg() {
-      return setterMethodsMustTakeOneArg() + ". Inherited method: %s";
-    }
-
-    final String setterMethodsMustReturnVoidOrBuilder() {
-      return process("@Component.Builder setter methods must return void, the builder,"
-          + " or a supertype of the builder");
-    }
-
-    final String inheritedSetterMethodsMustReturnVoidOrBuilder() {
-      return setterMethodsMustReturnVoidOrBuilder() + ". Inherited method: %s";
-    }
-
-    final String methodsMayNotHaveTypeParameters() {
-      return process("@Component.Builder methods must not have type parameters");
-    }
-
-    final String inheritedMethodsMayNotHaveTypeParameters() {
-      return methodsMayNotHaveTypeParameters() + ". Inherited method: %s";
-    }
-
-    abstract String nonBindsInstanceParametersMayNotBePrimitives();
-
-    final String inheritedNonBindsInstanceParametersMayNotBePrimitives() {
-      return nonBindsInstanceParametersMayNotBePrimitives() + ". Inherited method: %s";
-    }
-
-    final String factoryMethodReturnsSupertypeWithMissingMethods(
-        TypeElement component,
-        TypeElement componentBuilder,
-        TypeMirror returnType,
-        ExecutableElement buildMethod,
-        Set<ExecutableElement> additionalMethods) {
-      return String.format(
-          "%1$s.%2$s() returns %3$s, but %4$s declares additional component method(s): %5$s. In "
-              + "order to provide type-safe access to these methods, override %2$s() to return "
-              + "%4$s",
-          componentBuilder.getQualifiedName(),
-          buildMethod.getSimpleName(),
-          returnType,
-          component.getQualifiedName(),
-          Joiner.on(", ").join(additionalMethods));
-    }
-
-    final String bindsInstanceNotAllowedOnBothSetterMethodAndParameter() {
-      return process("@Component.Builder setter methods may not have @BindsInstance on both the "
-          + "method and its parameter; choose one or the other");
-    }
-
-    final String inheritedBindsInstanceNotAllowedOnBothSetterMethodAndParameter() {
-      return bindsInstanceNotAllowedOnBothSetterMethodAndParameter() + ". Inherited method: %s";
-    }
-  }
-
-  private static final class BuilderMessages extends ComponentCreatorMessages {
-    BuilderMessages(Function<String, String> transformation) {
-      super(transformation);
-    }
-
-    @Override
-    String missingFactoryMethod() {
-      return process(
-          "@Component.Builder types must have exactly one no-args method that "
-              + " returns the @Component type");
-    }
-
-    @Override
-    String multipleSettersForModuleOrDependencyType() {
-      return process(
-          "@Component.Builder types must not have more than one setter method per module or "
-              + "dependency, but %s is set by %s");
-    }
-
-    @Override
-    String extraSetters() {
-      return process(
-          "@Component.Builder has setters for modules or components that aren't required: %s");
-    }
-
-    @Override
-    String missingSetters() {
-      return process(
-          "@Component.Builder is missing setters for required modules or components: %s");
-    }
-
-    @Override
-    String twoFactoryMethods() {
-      return process(
-          "@Component.Builder types must have exactly one zero-arg method, and that"
-              + " method must return the @Component type. Already found: %s");
-    }
-
-    @Override
-    String inheritedTwoFactoryMethods() {
-      return process(
-          "@Component.Builder types must have exactly one zero-arg method, and that"
-              + " method must return the @Component type. Found %s and %s");
-    }
-
-    @Override
-    String factoryMethodMustReturnComponentType() {
-      return process(
-          "@Component.Builder methods that have no arguments must return the @Component type or a "
-              + "supertype of the @Component");
-    }
-
-    @Override
-    String factoryMethodMayNotBeAnnotatedWithBindsInstance() {
-      return process(
-          "@Component.Builder no-arg build methods may not be annotated with @BindsInstance");
-    }
-
-    @Override
-    String nonBindsInstanceParametersMayNotBePrimitives() {
-      return process(
-          "@Component.Builder methods that are not annotated with @BindsInstance "
-              + "must take either a module or a component dependency, not a primitive");
-    }
-  }
-
-  private static final class FactoryMessages extends ComponentCreatorMessages {
-    FactoryMessages(Function<String, String> transformation) {
-      super(transformation.andThen(FACTORY));
-    }
-
-    @Override
-    String missingFactoryMethod() {
-      return process(
-          "@Component.Factory types must have exactly one method that "
-              + "returns the @Component type");
-    }
-
-    @Override
-    String multipleSettersForModuleOrDependencyType() {
-      return process(
-          "@Component.Factory methods must not have more than one parameter per module or "
-              + "dependency, but %s is set by %s");
-    }
-
-    @Override
-    String extraSetters() {
-      return process(
-          "@Component.Factory method has parameters for modules or components that aren't "
-              + "required: %s");
-    }
-
-    @Override
-    String missingSetters() {
-      return process(
-          "@Component.Factory method is missing parameters for required modules or components: %s");
-    }
-
-    @Override
-    String twoFactoryMethods() {
-      return process(
-          "@Component.Factory types must have exactly one abstract method. Already found: %s");
-    }
-
-    @Override
-    String inheritedTwoFactoryMethods() {
-      return twoFactoryMethods();
-    }
-
-    @Override
-    String factoryMethodMustReturnComponentType() {
-      return process(
-          "@Component.Factory abstract methods must return the @Component type or a "
-              + "supertype of the @Component");
-    }
-
-    @Override
-    String factoryMethodMayNotBeAnnotatedWithBindsInstance() {
-      return process("@Component.Factory method may not be annotated with @BindsInstance");
-    }
-
-    @Override
-    String nonBindsInstanceParametersMayNotBePrimitives() {
-      return process(
-          "@Component.Factory method parameters that are not annotated with @BindsInstance "
-              + "must be either a module or a component dependency, not a primitive");
-    }
-  }
-
-  private ErrorMessages() {}
-}
diff --git a/java/dagger/internal/codegen/FactoryGenerator.java b/java/dagger/internal/codegen/FactoryGenerator.java
deleted file mode 100644
index d367bc5..0000000
--- a/java/dagger/internal/codegen/FactoryGenerator.java
+++ /dev/null
@@ -1,290 +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.collect.Maps.transformValues;
-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.ContributionBinding.FactoryCreationStrategy.DELEGATE;
-import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.SINGLETON_INSTANCE;
-import static dagger.internal.codegen.GwtCompatibility.gwtIncompatibleAnnotation;
-import static dagger.internal.codegen.SourceFiles.bindingTypeElementTypeVariableNames;
-import static dagger.internal.codegen.SourceFiles.frameworkFieldUsages;
-import static dagger.internal.codegen.SourceFiles.frameworkTypeUsageStatement;
-import static dagger.internal.codegen.SourceFiles.generateBindingFieldsForDependencies;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-import static dagger.internal.codegen.SourceFiles.parameterizedGeneratedTypeNameForBinding;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings;
-import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.factoryOf;
-import static dagger.model.BindingKind.PROVISION;
-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;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.Factory;
-import dagger.internal.Preconditions;
-import dagger.internal.codegen.InjectionMethods.InjectionSiteMethod;
-import dagger.internal.codegen.InjectionMethods.ProvisionMethod;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import java.util.List;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-
-/**
- * Generates {@link Factory} implementations from {@link ProvisionBinding} instances for
- * {@link Inject} constructors.
- */
-final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding> {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  FactoryGenerator(
-      Filer filer,
-      SourceVersion sourceVersion,
-      DaggerTypes types,
-      DaggerElements elements,
-      CompilerOptions compilerOptions) {
-    super(filer, elements, sourceVersion);
-    this.types = types;
-    this.elements = elements;
-    this.compilerOptions = compilerOptions;
-  }
-
-  @Override
-  ClassName nameGeneratedType(ProvisionBinding binding) {
-    return generatedClassNameForBinding(binding);
-  }
-
-  @Override
-  Element originatingElement(ProvisionBinding binding) {
-    // we only create factories for bindings that have a binding element
-    return binding.bindingElement().get();
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, ProvisionBinding binding) {
-    // We don't want to write out resolved bindings -- we want to write out the generic version.
-    checkArgument(!binding.unresolved().isPresent());
-    checkArgument(binding.bindingElement().isPresent());
-
-    return binding.factoryCreationStrategy().equals(DELEGATE)
-        ? Optional.empty()
-        : Optional.of(factoryBuilder(binding));
-  }
-
-  private TypeSpec.Builder factoryBuilder(ProvisionBinding binding) {
-    TypeSpec.Builder factoryBuilder =
-        classBuilder(nameGeneratedType(binding))
-            .addModifiers(PUBLIC, FINAL)
-            .addSuperinterface(factoryTypeName(binding))
-            .addTypeVariables(bindingTypeElementTypeVariableNames(binding));
-
-    addConstructorAndFields(binding, factoryBuilder);
-    factoryBuilder.addMethod(getMethod(binding));
-    addCreateMethod(binding, factoryBuilder);
-
-    factoryBuilder.addMethod(
-        ProvisionMethod.create(binding, compilerOptions, elements).toMethodSpec());
-    gwtIncompatibleAnnotation(binding).ifPresent(factoryBuilder::addAnnotation);
-
-    return factoryBuilder;
-  }
-
-  private void addConstructorAndFields(ProvisionBinding binding, TypeSpec.Builder factoryBuilder) {
-    if (binding.factoryCreationStrategy().equals(SINGLETON_INSTANCE)) {
-      return;
-    }
-    // TODO(user): Make the constructor private?
-    MethodSpec.Builder constructor = constructorBuilder().addModifiers(PUBLIC);
-    constructorParams(binding).forEach(
-        param -> {
-          constructor.addParameter(param).addStatement("this.$1N = $1N", param);
-          factoryBuilder.addField(
-              FieldSpec.builder(param.type, param.name, PRIVATE, FINAL).build());
-        });
-    factoryBuilder.addMethod(constructor.build());
-  }
-
-  private ImmutableList<ParameterSpec> constructorParams(ProvisionBinding binding) {
-    ImmutableList.Builder<ParameterSpec> params = ImmutableList.builder();
-    moduleParameter(binding).ifPresent(params::add);
-    frameworkFields(binding).values().forEach(field -> params.add(toParameter(field)));
-    return params.build();
-  }
-
-  private Optional<ParameterSpec> moduleParameter(ProvisionBinding binding) {
-    if (binding.requiresModuleInstance()) {
-      // TODO(user, dpb): Should this use contributingModule()?
-      TypeName type = TypeName.get(binding.bindingTypeElement().get().asType());
-      return Optional.of(ParameterSpec.builder(type, "module").build());
-    }
-    return Optional.empty();
-  }
-
-  private ImmutableMap<Key, FieldSpec> frameworkFields(ProvisionBinding binding) {
-    UniqueNameSet uniqueFieldNames = new UniqueNameSet();
-    // TODO(user, dpb): Add a test for the case when a Factory parameter is named "module".
-    if (binding.requiresModuleInstance()) {
-      uniqueFieldNames.claim("module");
-    }
-    return ImmutableMap.copyOf(
-        transformValues(
-            generateBindingFieldsForDependencies(binding),
-            field ->
-                FieldSpec.builder(
-                        field.type(), uniqueFieldNames.getUniqueName(field.name()), PRIVATE, FINAL)
-                    .build()));
-  }
-
-  private void addCreateMethod(ProvisionBinding binding, TypeSpec.Builder factoryBuilder) {
-    // If constructing a factory for @Inject or @Provides bindings, we use a static create method
-    // so that generated components can avoid having to refer to the generic types
-    // of the factory.  (Otherwise they may have visibility problems referring to the types.)
-    MethodSpec.Builder createMethodBuilder =
-        methodBuilder("create")
-            .addModifiers(PUBLIC, STATIC)
-            .returns(parameterizedGeneratedTypeNameForBinding(binding))
-            .addTypeVariables(bindingTypeElementTypeVariableNames(binding));
-
-    switch (binding.factoryCreationStrategy()) {
-      case SINGLETON_INSTANCE:
-        FieldSpec.Builder instanceFieldBuilder =
-            FieldSpec.builder(nameGeneratedType(binding), "INSTANCE", PRIVATE, STATIC, FINAL)
-                .initializer("new $T()", nameGeneratedType(binding));
-
-        if (!bindingTypeElementTypeVariableNames(binding).isEmpty()) {
-          // If the factory has type parameters, ignore them in the field declaration & initializer
-          instanceFieldBuilder.addAnnotation(suppressWarnings(RAWTYPES));
-
-          createMethodBuilder.addAnnotation(suppressWarnings(UNCHECKED));
-        }
-        createMethodBuilder.addStatement("return INSTANCE");
-        factoryBuilder.addField(instanceFieldBuilder.build());
-        break;
-      case CLASS_CONSTRUCTOR:
-        List<ParameterSpec> params = constructorParams(binding);
-        createMethodBuilder.addParameters(params);
-        createMethodBuilder.addStatement(
-            "return new $T($L)",
-            parameterizedGeneratedTypeNameForBinding(binding),
-            makeParametersCodeBlock(Lists.transform(params, input -> CodeBlock.of("$N", input))));
-        break;
-      default:
-        throw new AssertionError();
-    }
-    factoryBuilder.addMethod(createMethodBuilder.build());
-  }
-
-  private MethodSpec getMethod(ProvisionBinding binding) {
-    TypeName providedTypeName = providedTypeName(binding);
-    MethodSpec.Builder getMethod =
-        methodBuilder("get")
-            .addAnnotation(Override.class)
-            .addModifiers(PUBLIC)
-            .returns(providedTypeName);
-
-    ImmutableMap<Key, FieldSpec> frameworkFields = frameworkFields(binding);
-    CodeBlock parametersCodeBlock =
-        makeParametersCodeBlock(
-            frameworkFieldUsages(binding.provisionDependencies(), frameworkFields).values());
-
-    if (binding.kind().equals(PROVISION)) {
-      binding
-          .nullableType()
-          .ifPresent(nullableType -> CodeBlocks.addAnnotation(getMethod, nullableType));
-      getMethod.addStatement(
-          "return $L",
-          ProvisionMethod.invoke(
-              binding,
-              request ->
-                  frameworkTypeUsageStatement(
-                      CodeBlock.of("$N", frameworkFields.get(request.key())), request.kind()),
-              nameGeneratedType(binding),
-              binding.requiresModuleInstance()
-                  ? Optional.of(CodeBlock.of("module"))
-                  : Optional.empty(),
-              compilerOptions,
-              elements));
-    } else if (!binding.injectionSites().isEmpty()) {
-      CodeBlock instance = CodeBlock.of("instance");
-      getMethod
-          .addStatement("$1T $2L = new $1T($3L)", providedTypeName, instance, parametersCodeBlock)
-          .addCode(
-              InjectionSiteMethod.invokeAll(
-                  binding.injectionSites(),
-                  nameGeneratedType(binding),
-                  instance,
-                  binding.key().type(),
-                  types,
-                  frameworkFieldUsages(binding.dependencies(), frameworkFields)::get,
-                  elements))
-          .addStatement("return $L", instance);
-    } else {
-      getMethod.addStatement(
-          "return new $T($L)", providedTypeName, parametersCodeBlock);
-    }
-    return getMethod.build();
-  }
-
-  private static TypeName providedTypeName(ProvisionBinding binding) {
-    return TypeName.get(binding.contributedType());
-  }
-
-  private static TypeName factoryTypeName(ProvisionBinding binding) {
-    return factoryOf(providedTypeName(binding));
-  }
-
-  private static ParameterSpec toParameter(FieldSpec field) {
-    return ParameterSpec.builder(field.type, field.name).build();
-  }
-
-  /**
-   * Returns {@code Preconditions.checkNotNull(providesMethodInvocation)} with a message suitable
-   * for {@code @Provides} methods.
-   */
-  static CodeBlock checkNotNullProvidesMethod(CodeBlock providesMethodInvocation) {
-    return CodeBlock.of(
-        "$T.checkNotNull($L, $S)",
-        Preconditions.class,
-        providesMethodInvocation,
-        "Cannot return null from a non-@Nullable @Provides method");
-  }
-}
diff --git a/java/dagger/internal/codegen/FeatureStatus.java b/java/dagger/internal/codegen/FeatureStatus.java
deleted file mode 100644
index 9ff254e..0000000
--- a/java/dagger/internal/codegen/FeatureStatus.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-/** Allows options to control how features in component processing are enabled. */
-enum FeatureStatus {
-  ENABLED,
-  DISABLED;
-}
diff --git a/java/dagger/internal/codegen/Formatter.java b/java/dagger/internal/codegen/Formatter.java
deleted file mode 100644
index 53d4f9a..0000000
--- a/java/dagger/internal/codegen/Formatter.java
+++ /dev/null
@@ -1,96 +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.checkElementIndex;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-
-/**
- * A formatter which transforms an instance of a particular type into a string
- * representation.
- *
- * @param <T> the type of the object to be transformed.
- */
-abstract class Formatter<T> implements Function<T, String> {
-
-  static final String INDENT = "    ";
-  static final String DOUBLE_INDENT = INDENT + INDENT;
-  private static final int LIST_LIMIT = 10;
-
-  /**
-   * Performs the transformation of an object into a string representation.
-   */
-  public abstract String format(T object);
-
-  /**
-   * Performs the transformation of an object into a string representation in conformity with the
-   * {@link Function}{@code <T, String>} contract, delegating to {@link #format(Object)}.
-   *
-   * @deprecated Call {@link #format(Object)} instead. This method exists to make formatters easy to
-   *     use when functions are required, but shouldn't be called directly.
-   */
-  @SuppressWarnings("javadoc")
-  @Deprecated
-  @Override
-  public final String apply(T object) {
-    return format(object);
-  }
-
-  /** Formats {@code items}, one per line. Stops after {@value #LIST_LIMIT} items. */
-  public void formatIndentedList(
-      StringBuilder builder, Iterable<? extends T> items, int indentLevel) {
-    for (T item : Iterables.limit(items, LIST_LIMIT)) {
-      String formatted = format(item);
-      if (formatted.isEmpty()) {
-        continue;
-      }
-      builder.append('\n');
-      appendIndent(builder, indentLevel);
-      builder.append(formatted);
-    }
-    int numberOfOtherItems = Iterables.size(items) - LIST_LIMIT;
-    if (numberOfOtherItems > 0) {
-      builder.append('\n');
-      appendIndent(builder, indentLevel);
-      builder.append("and ").append(numberOfOtherItems).append(" other");
-    }
-    if (numberOfOtherItems > 1) {
-      builder.append('s');
-    }
-  }
-
-  private void appendIndent(StringBuilder builder, int indentLevel) {
-    for (int i = 0; i < indentLevel; i++) {
-      builder.append(INDENT);
-    }
-  }
-
-  static String formatArgumentInList(int index, int size, CharSequence name) {
-    checkElementIndex(index, size);
-    StringBuilder builder = new StringBuilder();
-    if (index > 0) {
-      builder.append("…, ");
-    }
-    builder.append(name);
-    if (index < size - 1) {
-      builder.append(", …");
-    }
-    return builder.toString();
-  }
-}
diff --git a/java/dagger/internal/codegen/ForwardingCompilerOptions.java b/java/dagger/internal/codegen/ForwardingCompilerOptions.java
deleted file mode 100644
index 4a1deda..0000000
--- a/java/dagger/internal/codegen/ForwardingCompilerOptions.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 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.checkNotNull;
-
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-
-/** A {@link CompilerOptions} object that delegates to another one. */
-class ForwardingCompilerOptions extends CompilerOptions {
-
-  private final CompilerOptions delegate;
-
-  ForwardingCompilerOptions(CompilerOptions delegate) {
-    this.delegate = checkNotNull(delegate);
-  }
-
-  @Override
-  boolean usesProducers() {
-    return delegate.usesProducers();
-  }
-
-  @Override
-  boolean fastInit() {
-    return delegate.fastInit();
-  }
-
-  @Override
-  boolean formatGeneratedSource() {
-    return delegate.formatGeneratedSource();
-  }
-
-  @Override
-  boolean writeProducerNameInToken() {
-    return delegate.writeProducerNameInToken();
-  }
-
-  @Override
-  Diagnostic.Kind nullableValidationKind() {
-    return delegate.nullableValidationKind();
-  }
-
-  @Override
-  Diagnostic.Kind privateMemberValidationKind() {
-    return delegate.privateMemberValidationKind();
-  }
-
-  @Override
-  Diagnostic.Kind staticMemberValidationKind() {
-    return delegate.staticMemberValidationKind();
-  }
-
-  @Override
-  boolean ignorePrivateAndStaticInjectionForComponent() {
-    return delegate.ignorePrivateAndStaticInjectionForComponent();
-  }
-
-  @Override
-  ValidationType scopeCycleValidationType() {
-    return delegate.scopeCycleValidationType();
-  }
-
-  @Override
-  boolean warnIfInjectionFactoryNotGeneratedUpstream() {
-    return delegate.warnIfInjectionFactoryNotGeneratedUpstream();
-  }
-
-  @Override
-  boolean headerCompilation() {
-    return delegate.headerCompilation();
-  }
-
-  @Override
-  boolean aheadOfTimeSubcomponents() {
-    return delegate.aheadOfTimeSubcomponents();
-  }
-
-  @Override
-  boolean forceUseSerializedComponentImplementations() {
-    return delegate.forceUseSerializedComponentImplementations();
-  }
-
-  @Override
-  boolean emitModifiableMetadataAnnotations() {
-    return delegate.emitModifiableMetadataAnnotations();
-  }
-
-  @Override
-  boolean useGradleIncrementalProcessing() {
-    return delegate.useGradleIncrementalProcessing();
-  }
-
-  @Override
-  ValidationType fullBindingGraphValidationType(TypeElement element) {
-    return delegate.fullBindingGraphValidationType(element);
-  }
-
-  @Override
-  Diagnostic.Kind moduleHasDifferentScopesDiagnosticKind() {
-    return delegate.moduleHasDifferentScopesDiagnosticKind();
-  }
-
-  @Override
-  ValidationType explicitBindingConflictsWithInjectValidationType() {
-    return delegate.explicitBindingConflictsWithInjectValidationType();
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkDependency.java b/java/dagger/internal/codegen/FrameworkDependency.java
deleted file mode 100644
index feea7a0..0000000
--- a/java/dagger/internal/codegen/FrameworkDependency.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.google.auto.value.AutoValue;
-import dagger.model.Key;
-
-/**
- * The framework class and binding key for a resolved dependency of a binding. If a binding has
- * several dependencies for a key, then only one instance of this class will represent them all.
- *
- * <p>In the following example, the binding {@code provideFoo()} has two dependency requests:
- *
- * <ol>
- *   <li>{@code Bar bar}
- *   <li>{@code Provider<Bar> barProvider}
- * </ol>
- *
- * But they both can be satisfied with the same instance of {@code Provider<Bar>}. So one instance
- * of {@code FrameworkDependency} will be used for both. Its {@link #key()} will be for {@code Bar},
- * and its {@link #frameworkType()} will be {@link FrameworkType#PROVIDER}.
- *
- * <pre><code>
- *   {@literal @Provides} static Foo provideFoo(Bar bar, {@literal Provider<Bar>} barProvider) {
- *     return new Foo(…);
- *   }
- * </code></pre>
- */
-@AutoValue
-abstract class FrameworkDependency {
-
-  /** The fully-resolved key shared by all the dependency requests. */
-  abstract Key key();
-
-  /** The type of the framework dependency. */
-  abstract FrameworkType frameworkType();
-
-  /** The framework class to use for this dependency. */
-  final Class<?> frameworkClass() {
-    return frameworkType().frameworkClass();
-  }
-
-  /** Returns a new instance with the given key and type. */
-  static FrameworkDependency create(Key key, FrameworkType frameworkType) {
-    return new AutoValue_FrameworkDependency(key, frameworkType);
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkField.java b/java/dagger/internal/codegen/FrameworkField.java
deleted file mode 100644
index de2ada0..0000000
--- a/java/dagger/internal/codegen/FrameworkField.java
+++ /dev/null
@@ -1,130 +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 dagger.model.BindingKind.MEMBERS_INJECTOR;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.CaseFormat;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementKindVisitor8;
-
-/**
- * A value object that represents a field in the generated Component class.
- *
- * <p>Examples:
- * <ul>
- *   <li>{@code Provider<String>}
- *   <li>{@code Producer<Widget>}
- *   <li>{@code Provider<Map<SomeMapKey, MapValue>>}.
- * </ul>
- */
-@AutoValue
-abstract class FrameworkField {
-
-  /**
-   * Creates a framework field.
-   * 
-   * @param frameworkClassName the name of the framework class (e.g., {@link javax.inject.Provider})
-   * @param valueTypeName the name of the type parameter of the framework class (e.g., {@code Foo}
-   *     for {@code Provider<Foo>}
-   * @param fieldName the name of the field
-   */
-  static FrameworkField create(
-      ClassName frameworkClassName, TypeName valueTypeName, String fieldName) {
-    String suffix = frameworkClassName.simpleName();
-    return new AutoValue_FrameworkField(
-        ParameterizedTypeName.get(frameworkClassName, valueTypeName),
-        fieldName.endsWith(suffix) ? fieldName : fieldName + suffix);
-  }
-
-  /**
-   * A framework field for a {@link ResolvedBindings}.
-   * 
-   * @param frameworkClass if present, the field will use this framework class instead of the normal
-   *     one for the bindings
-   */
-  static FrameworkField forResolvedBindings(
-      ResolvedBindings resolvedBindings, Optional<ClassName> frameworkClass) {
-    return create(
-        frameworkClass.orElse(
-            ClassName.get(
-                FrameworkType.forBindingType(resolvedBindings.bindingType()).frameworkClass())),
-        TypeName.get(fieldValueType(resolvedBindings)),
-        frameworkFieldName(resolvedBindings));
-  }
-
-  private static TypeMirror fieldValueType(ResolvedBindings resolvedBindings) {
-    return resolvedBindings.isMultibindingContribution()
-        ? resolvedBindings.contributionBinding().contributedType()
-        : resolvedBindings.key().type();
-  }
-
-  private static String frameworkFieldName(ResolvedBindings resolvedBindings) {
-    if (!resolvedBindings.contributionBindings().isEmpty()) {
-      ContributionBinding binding = resolvedBindings.contributionBinding();
-      if (binding.bindingElement().isPresent()) {
-        String name = BINDING_ELEMENT_NAME.visit(binding.bindingElement().get(), binding);
-        return binding.kind().equals(MEMBERS_INJECTOR)
-            ? name + "MembersInjector"
-            : name;
-      }
-    }
-    return KeyVariableNamer.name(resolvedBindings.key());
-  }
-
-  private static final ElementVisitor<String, Binding> BINDING_ELEMENT_NAME =
-      new ElementKindVisitor8<String, Binding>() {
-
-        @Override
-        protected String defaultAction(Element e, Binding p) {
-          throw new IllegalArgumentException("Unexpected binding " + p);
-        }
-
-        @Override
-        public String visitExecutableAsConstructor(ExecutableElement e, Binding p) {
-          return visit(e.getEnclosingElement(), p);
-        }
-
-        @Override
-        public String visitExecutableAsMethod(ExecutableElement e, Binding p) {
-          return e.getSimpleName().toString();
-        }
-
-        @Override
-        public String visitType(TypeElement e, Binding p) {
-          return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, e.getSimpleName().toString());
-        }
-
-        @Override
-        public String visitVariableAsParameter(VariableElement e, Binding p) {
-          return e.getSimpleName().toString();
-        }
-      };
-
-  abstract ParameterizedTypeName type();
-  abstract String name();
-}
diff --git a/java/dagger/internal/codegen/FrameworkFieldInitializer.java b/java/dagger/internal/codegen/FrameworkFieldInitializer.java
deleted file mode 100644
index a3de083..0000000
--- a/java/dagger/internal/codegen/FrameworkFieldInitializer.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.ComponentImplementation.FieldSpecKind.FRAMEWORK_FIELD;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.DelegateFactory;
-import dagger.internal.codegen.javapoet.AnnotationSpecs;
-import dagger.internal.codegen.javapoet.TypeNames;
-import dagger.producers.internal.DelegateProducer;
-import java.util.Optional;
-
-/**
- * An object that can initialize a framework-type component field for a binding. An instance should
- * be created for each field.
- */
-class FrameworkFieldInitializer implements FrameworkInstanceSupplier {
-
-  /**
-   * An object that can determine the expression to use to assign to the component field for a
-   * binding.
-   */
-  interface FrameworkInstanceCreationExpression {
-    /** Returns the expression to use to assign to the component field for the binding. */
-    CodeBlock creationExpression();
-
-    /**
-     * Returns the framework class to use for the field, if different from the one implied by the
-     * binding. This implementation returns {@link Optional#empty()}.
-     */
-    default Optional<ClassName> alternativeFrameworkClass() {
-      return Optional.empty();
-    }
-
-    /**
-     * Returns {@code true} if instead of using {@link #creationExpression()} to create a framework
-     * instance, a case in {@link InnerSwitchingProviders} should be created for this binding.
-     */
-    // TODO(ronshapiro): perhaps this isn't the right approach. Instead of saying "Use
-    // SetFactory.EMPTY because you will only get 1 class for all types of bindings that use
-    // SetFactory", maybe we should still use an inner switching provider but the same switching
-    // provider index for all cases.
-    default boolean useInnerSwitchingProvider() {
-      return true;
-    }
-  }
-
-  private final ComponentImplementation componentImplementation;
-  private final ResolvedBindings resolvedBindings;
-  private final FrameworkInstanceCreationExpression frameworkInstanceCreationExpression;
-  private FieldSpec fieldSpec;
-  private InitializationState fieldInitializationState = InitializationState.UNINITIALIZED;
-
-  FrameworkFieldInitializer(
-      ComponentImplementation componentImplementation,
-      ResolvedBindings resolvedBindings,
-      FrameworkInstanceCreationExpression frameworkInstanceCreationExpression) {
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.resolvedBindings = checkNotNull(resolvedBindings);
-    this.frameworkInstanceCreationExpression = checkNotNull(frameworkInstanceCreationExpression);
-  }
-
-  /**
-   * Returns the {@link MemberSelect} for the framework field, and adds the field and its
-   * initialization code to the component if it's needed and not already added.
-   */
-  @Override
-  public final MemberSelect memberSelect() {
-    initializeField();
-    return MemberSelect.localField(componentImplementation.name(), checkNotNull(fieldSpec).name);
-  }
-
-  /** Adds the field and its initialization code to the component. */
-  private void initializeField() {
-    switch (fieldInitializationState) {
-      case UNINITIALIZED:
-        // Change our state in case we are recursively invoked via initializeBindingExpression
-        fieldInitializationState = InitializationState.INITIALIZING;
-        CodeBlock.Builder codeBuilder = CodeBlock.builder();
-        CodeBlock fieldInitialization = frameworkInstanceCreationExpression.creationExpression();
-        CodeBlock initCode = CodeBlock.of("this.$N = $L;", getOrCreateField(), fieldInitialization);
-
-        if (isReplacingSuperclassFrameworkInstance()
-            || fieldInitializationState == InitializationState.DELEGATED) {
-          codeBuilder.add(
-              "$T.setDelegate($N, $L);", delegateType(), fieldSpec, fieldInitialization);
-        } else {
-          codeBuilder.add(initCode);
-        }
-        componentImplementation.addInitialization(codeBuilder.build());
-
-        fieldInitializationState = InitializationState.INITIALIZED;
-        break;
-
-      case INITIALIZING:
-        // We were recursively invoked, so create a delegate factory instead
-        fieldInitializationState = InitializationState.DELEGATED;
-        componentImplementation.addInitialization(
-            CodeBlock.of("this.$N = new $T<>();", getOrCreateField(), delegateType()));
-        break;
-
-      case DELEGATED:
-      case INITIALIZED:
-        break;
-    }
-  }
-
-  /**
-   * Adds a field representing the resolved bindings, optionally forcing it to use a particular
-   * binding type (instead of the type the resolved bindings would typically use).
-   */
-  private FieldSpec getOrCreateField() {
-    if (fieldSpec != null) {
-      return fieldSpec;
-    }
-    boolean useRawType = !componentImplementation.isTypeAccessible(resolvedBindings.key().type());
-    FrameworkField contributionBindingField =
-        FrameworkField.forResolvedBindings(
-            resolvedBindings, frameworkInstanceCreationExpression.alternativeFrameworkClass());
-
-    TypeName fieldType =
-        useRawType ? contributionBindingField.type().rawType : contributionBindingField.type();
-
-    FieldSpec.Builder contributionField =
-        FieldSpec.builder(
-            fieldType, componentImplementation.getUniqueFieldName(contributionBindingField.name()));
-    contributionField.addModifiers(PRIVATE);
-    if (useRawType) {
-      contributionField.addAnnotation(AnnotationSpecs.suppressWarnings(RAWTYPES));
-    }
-
-    if (isReplacingSuperclassFrameworkInstance()) {
-      // If a binding is modified in a subclass, the framework instance will be replaced in the
-      // subclass implementation. The superclass framework instance initialization will run first,
-      // however, and may refer to the modifiable binding method returning this type's modified
-      // framework instance before it is initialized, so we use a delegate factory as a placeholder
-      // until it has properly been initialized.
-      contributionField.initializer("new $T<>()", delegateType());
-    }
-
-    fieldSpec = contributionField.build();
-    componentImplementation.addField(FRAMEWORK_FIELD, fieldSpec);
-
-    return fieldSpec;
-  }
-
-  /**
-   * Returns true if this framework field is replacing a superclass's implementation of the
-   * framework field.
-   */
-  private boolean isReplacingSuperclassFrameworkInstance() {
-    return componentImplementation
-        .superclassImplementation()
-        .flatMap(
-            superclassImplementation ->
-                // TODO(b/117833324): can we constrain this further?
-                superclassImplementation.getModifiableBindingMethod(
-                    BindingRequest.bindingRequest(
-                        resolvedBindings.key(),
-                        isProvider() ? FrameworkType.PROVIDER : FrameworkType.PRODUCER_NODE)))
-        .isPresent();
-  }
-
-  private Class<?> delegateType() {
-    return isProvider() ? DelegateFactory.class : DelegateProducer.class;
-  }
-
-  private boolean isProvider() {
-    return resolvedBindings.bindingType().equals(BindingType.PROVISION)
-        && frameworkInstanceCreationExpression
-            .alternativeFrameworkClass()
-            .map(TypeNames.PROVIDER::equals)
-            .orElse(true);
-  }
-
-  /** Initialization state for a factory field. */
-  private enum InitializationState {
-    /** The field is {@code null}. */
-    UNINITIALIZED,
-
-    /**
-     * The field's dependencies are being set up. If the field is needed in this state, use a {@link
-     * DelegateFactory}.
-     */
-    INITIALIZING,
-
-    /**
-     * The field's dependencies are being set up, but the field can be used because it has already
-     * been set to a {@link DelegateFactory}.
-     */
-    DELEGATED,
-
-    /** The field is set to an undelegated factory. */
-    INITIALIZED;
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkInstanceBindingExpression.java b/java/dagger/internal/codegen/FrameworkInstanceBindingExpression.java
deleted file mode 100644
index 6f62d66..0000000
--- a/java/dagger/internal/codegen/FrameworkInstanceBindingExpression.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** A binding expression that uses a {@link FrameworkType} field. */
-abstract class FrameworkInstanceBindingExpression extends BindingExpression {
-  private final ResolvedBindings resolvedBindings;
-  private final FrameworkInstanceSupplier frameworkInstanceSupplier;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  FrameworkInstanceBindingExpression(
-      ResolvedBindings resolvedBindings,
-      FrameworkInstanceSupplier frameworkInstanceSupplier,
-      DaggerTypes types,
-      DaggerElements elements) {
-    this.resolvedBindings = checkNotNull(resolvedBindings);
-    this.frameworkInstanceSupplier = checkNotNull(frameworkInstanceSupplier);
-    this.types = checkNotNull(types);
-    this.elements = checkNotNull(elements);
-  }
-
-  /**
-   * The expression for the framework instance for this binding. The field will be {@link
-   * ComponentImplementation#addInitialization(CodeBlock) initialized} and {@link
-   * ComponentImplementation#addField(ComponentImplementation.FieldSpecKind, FieldSpec) added} to
-   * the component the first time this method is invoked.
-   */
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    MemberSelect memberSelect = frameworkInstanceSupplier.memberSelect();
-    TypeMirror contributedType = resolvedBindings.contributionBinding().contributedType();
-    TypeMirror expressionType =
-        isTypeAccessibleFrom(contributedType, requestingClass.packageName())
-                || isInlinedFactoryCreation(memberSelect)
-            ? types.wrapType(contributedType, frameworkType().frameworkClass())
-            : rawFrameworkType();
-    return Expression.create(expressionType, memberSelect.getExpressionFor(requestingClass));
-  }
-
-  /** Returns the framework type for the binding. */
-  protected abstract FrameworkType frameworkType();
-
-  /**
-   * Returns {@code true} if a factory is created inline each time it is requested. For example, in
-   * the initialization {@code this.fooProvider = Foo_Factory.create(Bar_Factory.create());}, {@code
-   * Bar_Factory} is considered to be inline.
-   *
-   * <p>This is used in {@link #getDependencyExpression(ClassName)} when determining the type of a
-   * factory. Normally if the {@link ContributionBinding#contributedType()} is not accessible from
-   * the component, the type of the expression will be a raw {@link javax.inject.Provider}. However,
-   * if the factory is created inline, even if contributed type is not accessible, javac will still
-   * be able to determine the type that is returned from the {@code Foo_Factory.create()} method.
-   */
-  private static boolean isInlinedFactoryCreation(MemberSelect memberSelect) {
-    return memberSelect.staticMember();
-  }
-
-  private DeclaredType rawFrameworkType() {
-    return types.getDeclaredType(elements.getTypeElement(frameworkType().frameworkClass()));
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkInstanceSupplier.java b/java/dagger/internal/codegen/FrameworkInstanceSupplier.java
deleted file mode 100644
index 4c45630..0000000
--- a/java/dagger/internal/codegen/FrameworkInstanceSupplier.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-/** An object that supplies a {@link MemberSelect} for a framework instance. */
-interface FrameworkInstanceSupplier {
-  /** Returns a {@link MemberSelect}, with possible side effects on the first call. */
-  MemberSelect memberSelect();
-}
diff --git a/java/dagger/internal/codegen/FrameworkType.java b/java/dagger/internal/codegen/FrameworkType.java
deleted file mode 100644
index f4e3779..0000000
--- a/java/dagger/internal/codegen/FrameworkType.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2016 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.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-import static dagger.model.RequestKind.INSTANCE;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import dagger.Lazy;
-import dagger.internal.DoubleCheck;
-import dagger.internal.ProviderOfLazy;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.RequestKind;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.internal.Producers;
-import java.util.Optional;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/** One of the core types initialized as fields in a generated component. */
-enum FrameworkType {
-  /** A {@link Provider}. */
-  PROVIDER {
-    @Override
-    Class<?> frameworkClass() {
-      return Provider.class;
-    }
-
-    @Override
-    Optional<RequestKind> requestKind() {
-      return Optional.of(RequestKind.PROVIDER);
-    }
-
-    @Override
-    CodeBlock to(RequestKind requestKind, CodeBlock from) {
-      switch (requestKind) {
-        case INSTANCE:
-          return CodeBlock.of("$L.get()", from);
-
-        case LAZY:
-          return CodeBlock.of("$T.lazy($L)", DoubleCheck.class, from);
-
-        case PROVIDER:
-          return from;
-
-        case PROVIDER_OF_LAZY:
-          return CodeBlock.of("$T.create($L)", ProviderOfLazy.class, from);
-
-        case PRODUCER:
-          return CodeBlock.of("$T.producerFromProvider($L)", Producers.class, from);
-
-        case FUTURE:
-          return CodeBlock.of("$T.immediateFuture($L)", Futures.class, to(INSTANCE, from));
-
-        case PRODUCED:
-          return CodeBlock.of("$T.successful($L)", Produced.class, to(INSTANCE, from));
-
-        default:
-          throw new IllegalArgumentException(
-              String.format("Cannot request a %s from a %s", requestKind, this));
-      }
-    }
-
-    @Override
-    Expression to(RequestKind requestKind, Expression from, DaggerTypes types) {
-      CodeBlock codeBlock = to(requestKind, from.codeBlock());
-      switch (requestKind) {
-        case INSTANCE:
-          return Expression.create(types.unwrapTypeOrObject(from.type()), codeBlock);
-
-        case PROVIDER:
-          return from;
-
-        case PROVIDER_OF_LAZY:
-          TypeMirror lazyType = types.rewrapType(from.type(), Lazy.class);
-          return Expression.create(types.wrapType(lazyType, Provider.class), codeBlock);
-
-        case FUTURE:
-          return Expression.create(
-              types.rewrapType(from.type(), ListenableFuture.class), codeBlock);
-
-        default:
-          return Expression.create(
-              types.rewrapType(from.type(), RequestKinds.frameworkClass(requestKind)), codeBlock);
-      }
-    }
-  },
-
-  /** A {@link Producer}. */
-  PRODUCER_NODE {
-    @Override
-    Class<?> frameworkClass() {
-      // TODO(cgdecker): Replace this with new class for representing internal producer nodes.
-      // Currently the new class is CancellableProducer, but it may be changed to ProducerNode and
-      // made to not implement Producer.
-      return Producer.class;
-    }
-
-    @Override
-    Optional<RequestKind> requestKind() {
-      return Optional.empty();
-    }
-
-    @Override
-    CodeBlock to(RequestKind requestKind, CodeBlock from) {
-      switch (requestKind) {
-        case FUTURE:
-          return CodeBlock.of("$L.get()", from);
-
-        case PRODUCER:
-          return from;
-
-        default:
-          throw new IllegalArgumentException(
-              String.format("Cannot request a %s from a %s", requestKind, this));
-      }
-    }
-
-    @Override
-    Expression to(RequestKind requestKind, Expression from, DaggerTypes types) {
-      switch (requestKind) {
-        case FUTURE:
-          return Expression.create(
-              types.rewrapType(from.type(), ListenableFuture.class),
-              to(requestKind, from.codeBlock()));
-
-        case PRODUCER:
-          return Expression.create(from.type(), to(requestKind, from.codeBlock()));
-
-        default:
-          throw new IllegalArgumentException(
-              String.format("Cannot request a %s from a %s", requestKind, this));
-      }
-    }
-  },
-  ;
-
-  /** Returns the framework type appropriate for fields for a given binding type. */
-  static FrameworkType forBindingType(BindingType bindingType) {
-    switch (bindingType) {
-      case PROVISION:
-        return PROVIDER;
-      case PRODUCTION:
-        return PRODUCER_NODE;
-      case MEMBERS_INJECTION:
-    }
-    throw new AssertionError(bindingType);
-  }
-
-  /** Returns the framework type that exactly matches the given request kind, if one exists. */
-  static Optional<FrameworkType> forRequestKind(RequestKind requestKind) {
-    switch (requestKind) {
-      case PROVIDER:
-        return Optional.of(FrameworkType.PROVIDER);
-      default:
-        return Optional.empty();
-    }
-  }
-
-  /** The class of fields of this type. */
-  abstract Class<?> frameworkClass();
-
-  /** Returns the {@link #frameworkClass()} parameterized with a type. */
-  ParameterizedTypeName frameworkClassOf(TypeName valueType) {
-    return ParameterizedTypeName.get(ClassName.get(frameworkClass()), valueType);
-  }
-
-  /** The request kind that an instance of this framework type can satisfy directly, if any. */
-  abstract Optional<RequestKind> requestKind();
-
-  /**
-   * Returns a {@link CodeBlock} that evaluates to a requested object given an expression that
-   * evaluates to an instance of this framework type.
-   *
-   * @param requestKind the kind of {@link DependencyRequest} that the returned expression can
-   *     satisfy
-   * @param from a {@link CodeBlock} that evaluates to an instance of this framework type
-   * @throws IllegalArgumentException if a valid expression cannot be generated for {@code
-   *     requestKind}
-   */
-  abstract CodeBlock to(RequestKind requestKind, CodeBlock from);
-
-  /**
-   * Returns an {@link Expression} that evaluates to a requested object given an expression that
-   * evaluates to an instance of this framework type.
-   *
-   * @param requestKind the kind of {@link DependencyRequest} that the returned expression can
-   *     satisfy
-   * @param from an expression that evaluates to an instance of this framework type
-   * @throws IllegalArgumentException if a valid expression cannot be generated for {@code
-   *     requestKind}
-   */
-  abstract Expression to(RequestKind requestKind, Expression from, DaggerTypes types);
-
-  @Override
-  public String toString() {
-    return UPPER_UNDERSCORE.to(UPPER_CAMEL, super.toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkTypeMapper.java b/java/dagger/internal/codegen/FrameworkTypeMapper.java
deleted file mode 100644
index 7746692..0000000
--- a/java/dagger/internal/codegen/FrameworkTypeMapper.java
+++ /dev/null
@@ -1,85 +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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingType.PRODUCTION;
-import static java.util.stream.Collectors.toSet;
-
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import dagger.producers.Producer;
-import java.util.Set;
-import javax.inject.Provider;
-
-/**
- * A mapper for associating a {@link RequestKind} to a {@link FrameworkType}, dependent on the type
- * of code to be generated (e.g., for {@link Provider} or {@link Producer}).
- */
-enum FrameworkTypeMapper {
-  FOR_PROVIDER() {
-    @Override
-    public FrameworkType getFrameworkType(RequestKind requestKind) {
-      switch (requestKind) {
-        case INSTANCE:
-        case PROVIDER:
-        case PROVIDER_OF_LAZY:
-        case LAZY:
-          return FrameworkType.PROVIDER;
-        case PRODUCED:
-        case PRODUCER:
-          throw new IllegalArgumentException(requestKind.toString());
-        default:
-          throw new AssertionError(requestKind);
-      }
-    }
-  },
-  FOR_PRODUCER() {
-    @Override
-    public FrameworkType getFrameworkType(RequestKind requestKind) {
-      switch (requestKind) {
-        case INSTANCE:
-        case PRODUCED:
-        case PRODUCER:
-          return FrameworkType.PRODUCER_NODE;
-        case PROVIDER:
-        case PROVIDER_OF_LAZY:
-        case LAZY:
-          return FrameworkType.PROVIDER;
-        default:
-          throw new AssertionError(requestKind);
-      }
-    }
-  };
-
-  static FrameworkTypeMapper forBindingType(BindingType bindingType) {
-    return bindingType.equals(PRODUCTION) ? FOR_PRODUCER : FOR_PROVIDER;
-  }
-
-  abstract FrameworkType getFrameworkType(RequestKind requestKind);
-
-  /**
-   * Returns the {@link FrameworkType} to use for a collection of requests of the same {@link Key}.
-   * This allows factories to only take a single argument for multiple requests of the same key.
-   */
-  FrameworkType getFrameworkType(Set<DependencyRequest> requests) {
-    Set<FrameworkType> frameworkTypes =
-        requests.stream().map(request -> getFrameworkType(request.kind())).collect(toSet());
-    return frameworkTypes.size() == 1 ? getOnlyElement(frameworkTypes) : FrameworkType.PROVIDER;
-  }
-}
diff --git a/java/dagger/internal/codegen/FrameworkTypes.java b/java/dagger/internal/codegen/FrameworkTypes.java
deleted file mode 100644
index 19d2eda..0000000
--- a/java/dagger/internal/codegen/FrameworkTypes.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreTypes.isType;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.Lazy;
-import dagger.MembersInjector;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.Set;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A collection of utility methods for dealing with Dagger framework types. A framework type is any
- * type that the framework itself defines.
- */
-final class FrameworkTypes {
-  private static final ImmutableSet<Class<?>> PROVISION_TYPES =
-      ImmutableSet.of(Provider.class, Lazy.class, MembersInjector.class);
-
-  // NOTE(beder): ListenableFuture is not considered a producer framework type because it is not
-  // defined by the framework, so we can't treat it specially in ordinary Dagger.
-  private static final ImmutableSet<Class<?>> PRODUCTION_TYPES =
-      ImmutableSet.of(Produced.class, Producer.class);
-
-  /** Returns true if the type represents a producer-related framework type. */
-  static boolean isProducerType(TypeMirror type) {
-    return isType(type) && typeIsOneOf(PRODUCTION_TYPES, type);
-  }
-
-  /** Returns true if the type represents a framework type. */
-  static boolean isFrameworkType(TypeMirror type) {
-    return isType(type)
-        && (typeIsOneOf(PROVISION_TYPES, type)
-            || typeIsOneOf(PRODUCTION_TYPES, type));
-  }
-
-  private static boolean typeIsOneOf(Set<Class<?>> classes, TypeMirror type) {
-    for (Class<?> clazz : classes) {
-      if (MoreTypes.isTypeOf(clazz, type)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private FrameworkTypes() {}
-}
diff --git a/java/dagger/internal/codegen/GenerationCompilerOptions.java b/java/dagger/internal/codegen/GenerationCompilerOptions.java
deleted file mode 100644
index 1b14a7e..0000000
--- a/java/dagger/internal/codegen/GenerationCompilerOptions.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * A {@link Qualifier} for bindings associated with the serialization/deserialization of {@link
- * dagger.internal.GenerationOptions}.
- */
-@Retention(RUNTIME)
-@Qualifier
-@interface GenerationCompilerOptions {}
diff --git a/java/dagger/internal/codegen/GenerationOptionsModule.java b/java/dagger/internal/codegen/GenerationOptionsModule.java
deleted file mode 100644
index aa3c461..0000000
--- a/java/dagger/internal/codegen/GenerationOptionsModule.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.Module;
-import dagger.Provides;
-import dagger.internal.GenerationOptions;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Optional;
-
-/** Adds bindings for serializing and rereading {@link GenerationOptions}. */
-@Module
-interface GenerationOptionsModule {
-  @Provides
-  @PerComponentImplementation
-  @GenerationCompilerOptions
-  static CompilerOptions generationOptions(
-      CompilerOptions defaultOptions,
-      ComponentImplementation componentImplementation,
-      DaggerElements elements) {
-    // Avoid looking up types that don't exist. Performance improves for large components.
-    if (!defaultOptions.aheadOfTimeSubcomponents()) {
-      return defaultOptions;
-    }
-    // Inspect the base implementation for the @GenerationOptions annotation. Even if
-    // componentImplementation is the base implementation, inspect it for the case where we are
-    // recomputing the ComponentImplementation from a previous compilation.
-    // TODO(b/117833324): consider adding a method that returns baseImplementation.orElse(this).
-    // The current state of the world is a little confusing and maybe not intuitive: the base
-    // implementation has no base implementation, but it _is_ a base implementation.
-    return Optional.of(componentImplementation.baseImplementation().orElse(componentImplementation))
-        .map(baseImplementation -> elements.getTypeElement(baseImplementation.name()))
-        // If this returns null, the type has not been generated yet and Optional will switch to an
-        // empty state. This means that we're currently generating componentImplementation, or that
-        // the base implementation is being generated in this round, and thus the options passed to
-        // this compilation are applicable
-        .map(typeElement -> typeElement.getAnnotation(GenerationOptions.class))
-        .map(defaultOptions::withGenerationOptions)
-        .orElse(defaultOptions);
-  }
-}
diff --git a/java/dagger/internal/codegen/GwtCompatibility.java b/java/dagger/internal/codegen/GwtCompatibility.java
deleted file mode 100644
index 34d8f6d..0000000
--- a/java/dagger/internal/codegen/GwtCompatibility.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.squareup.javapoet.AnnotationSpec;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Name;
-
-final class GwtCompatibility {
-
-  /**
-   * Returns a {@code @GwtIncompatible} annotation that is applied to {@code binding}'s {@link
-   * Binding#bindingElement()} or any enclosing type.
-   */
-  static Optional<AnnotationSpec> gwtIncompatibleAnnotation(Binding binding) {
-    checkArgument(binding.bindingElement().isPresent());
-    Element element = binding.bindingElement().get();
-    while (element != null) {
-      Optional<AnnotationSpec> gwtIncompatible =
-          element
-              .getAnnotationMirrors()
-              .stream()
-              .filter(annotation -> isGwtIncompatible(annotation))
-              .map(AnnotationSpec::get)
-              .findFirst();
-      if (gwtIncompatible.isPresent()) {
-        return gwtIncompatible;
-      }
-      element = element.getEnclosingElement();
-    }
-    return Optional.empty();
-  }
-
-  private static boolean isGwtIncompatible(AnnotationMirror annotation) {
-    Name simpleName = annotation.getAnnotationType().asElement().getSimpleName();
-    return simpleName.contentEquals("GwtIncompatible");
-  }
-}
diff --git a/java/dagger/internal/codegen/HjarSourceFileGenerator.java b/java/dagger/internal/codegen/HjarSourceFileGenerator.java
deleted file mode 100644
index 5c36322..0000000
--- a/java/dagger/internal/codegen/HjarSourceFileGenerator.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2017 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.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeSpec;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-
-/**
- * A source file generator that only writes the relevant code necessary for Bazel to create a
- * correct header (ABI) jar.
- */
-final class HjarSourceFileGenerator<T> extends SourceFileGenerator<T> {
-  private final SourceFileGenerator<T> delegate;
-
-  private HjarSourceFileGenerator(SourceFileGenerator<T> delegate) {
-    super(delegate);
-    this.delegate = delegate;
-  }
-
-  static <T> SourceFileGenerator<T> wrap(SourceFileGenerator<T> delegate) {
-    return new HjarSourceFileGenerator<>(delegate);
-  }
-
-  @Override
-  ClassName nameGeneratedType(T input) {
-    return delegate.nameGeneratedType(input);
-  }
-
-  @Override
-  Element originatingElement(T input) {
-    return delegate.originatingElement(input);
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, T input) {
-    return delegate
-        .write(generatedTypeName, input)
-        .map(completeType -> skeletonType(completeType.build()));
-  }
-
-  private TypeSpec.Builder skeletonType(TypeSpec completeType) {
-    TypeSpec.Builder skeleton =
-        classBuilder(completeType.name)
-            .addSuperinterfaces(completeType.superinterfaces)
-            .addTypeVariables(completeType.typeVariables)
-            .addModifiers(completeType.modifiers.toArray(new Modifier[0]))
-            .addAnnotations(completeType.annotations);
-
-    if (!completeType.superclass.equals(ClassName.OBJECT)) {
-      skeleton.superclass(completeType.superclass);
-    }
-
-    completeType.methodSpecs.stream()
-        .filter(method -> !method.modifiers.contains(PRIVATE) || method.isConstructor())
-        .map(this::skeletonMethod)
-        .forEach(skeleton::addMethod);
-
-    completeType.fieldSpecs.stream()
-        .filter(field -> !field.modifiers.contains(PRIVATE))
-        .map(this::skeletonField)
-        .forEach(skeleton::addField);
-
-    completeType.typeSpecs.stream()
-        .map(type -> skeletonType(type).build())
-        .forEach(skeleton::addType);
-
-    return skeleton;
-  }
-
-  private MethodSpec skeletonMethod(MethodSpec completeMethod) {
-    MethodSpec.Builder skeleton =
-        completeMethod.isConstructor()
-            ? constructorBuilder()
-            : methodBuilder(completeMethod.name).returns(completeMethod.returnType);
-
-    if (completeMethod.isConstructor()) {
-      // Code in Turbine must (for technical reasons in javac) have a valid super() call for
-      // constructors, otherwise javac will bark, and Turbine has no way to avoid this. So we retain
-      // constructor method bodies if they do exist
-      skeleton.addCode(completeMethod.code);
-    }
-
-    return skeleton
-        .addModifiers(completeMethod.modifiers)
-        .addTypeVariables(completeMethod.typeVariables)
-        .addParameters(completeMethod.parameters)
-        .addExceptions(completeMethod.exceptions)
-        .varargs(completeMethod.varargs)
-        .addAnnotations(completeMethod.annotations)
-        .build();
-  }
-
-  private FieldSpec skeletonField(FieldSpec completeField) {
-    return FieldSpec.builder(
-            completeField.type,
-            completeField.name,
-            completeField.modifiers.toArray(new Modifier[0]))
-        .addAnnotations(completeField.annotations)
-        .build();
-  }
-}
diff --git a/java/dagger/internal/codegen/ImmediateFutureBindingExpression.java b/java/dagger/internal/codegen/ImmediateFutureBindingExpression.java
deleted file mode 100644
index 69b107c..0000000
--- a/java/dagger/internal/codegen/ImmediateFutureBindingExpression.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import javax.lang.model.SourceVersion;
-
-final class ImmediateFutureBindingExpression extends BindingExpression {
-
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-  private final SourceVersion sourceVersion;
-  private final Key key;
-
-  ImmediateFutureBindingExpression(
-      ResolvedBindings resolvedBindings,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      SourceVersion sourceVersion) {
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-    this.types = checkNotNull(types);
-    this.sourceVersion = checkNotNull(sourceVersion);
-    this.key = resolvedBindings.key();
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    return Expression.create(
-        types.wrapType(key.type(), ListenableFuture.class),
-        CodeBlock.of("$T.immediateFuture($L)", Futures.class, instanceExpression(requestingClass)));
-  }
-
-  private CodeBlock instanceExpression(ClassName requestingClass) {
-    Expression expression =
-        componentBindingExpressions.getDependencyExpression(
-            bindingRequest(key, RequestKind.INSTANCE), requestingClass);
-    if (sourceVersion.compareTo(SourceVersion.RELEASE_7) <= 0) {
-      // Java 7 type inference is not as strong as in Java 8, and therefore some generated code must
-      // cast.
-      //
-      // For example, javac7 cannot detect that Futures.immediateFuture(ImmutableSet.of("T"))
-      // can safely be assigned to ListenableFuture<Set<T>>.
-      if (!types.isSameType(expression.type(), key.type())) {
-        return CodeBlock.of(
-            "($T) $L", types.accessibleType(key.type(), requestingClass), expression.codeBlock());
-      }
-    }
-    return expression.codeBlock();
-  }
-}
diff --git a/java/dagger/internal/codegen/InaccessibleMapKeyProxyGenerator.java b/java/dagger/internal/codegen/InaccessibleMapKeyProxyGenerator.java
deleted file mode 100644
index 19c4d19..0000000
--- a/java/dagger/internal/codegen/InaccessibleMapKeyProxyGenerator.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 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.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-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 com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-
-/**
- * Generates a class that exposes a non-{@code public} {@link
- * ContributionBinding#mapKeyAnnotation()} @MapKey} annotation.
- */
-final class InaccessibleMapKeyProxyGenerator extends SourceFileGenerator<ContributionBinding> {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  @Inject
-  InaccessibleMapKeyProxyGenerator(
-      Filer filer, DaggerTypes types, DaggerElements elements, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-    this.types = types;
-    this.elements = elements;
-  }
-
-  @Override
-  ClassName nameGeneratedType(ContributionBinding binding) {
-    return MapKeys.mapKeyProxyClassName(binding);
-  }
-
-  @Override
-  Element originatingElement(ContributionBinding binding) {
-    // a map key is only ever present on bindings that have a binding element
-    return binding.bindingElement().get();
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedName, ContributionBinding binding) {
-    return MapKeys.mapKeyFactoryMethod(binding, types, elements)
-        .map(
-            method ->
-                classBuilder(generatedName)
-                    .addModifiers(PUBLIC, FINAL)
-                    .addMethod(constructorBuilder().addModifiers(PRIVATE).build())
-                    .addMethod(method));
-  }
-}
diff --git a/java/dagger/internal/codegen/IncompatiblyScopedBindingsValidator.java b/java/dagger/internal/codegen/IncompatiblyScopedBindingsValidator.java
deleted file mode 100644
index d649e46..0000000
--- a/java/dagger/internal/codegen/IncompatiblyScopedBindingsValidator.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.Formatter.INDENT;
-import static dagger.internal.codegen.Scopes.getReadableSource;
-import static dagger.internal.codegen.langmodel.DaggerElements.closestEnclosingTypeElement;
-import static dagger.model.BindingKind.INJECTION;
-import static java.util.stream.Collectors.joining;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Multimaps;
-import dagger.model.Binding;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.tools.Diagnostic;
-
-/**
- * Reports an error for any component that uses bindings with scopes that are not assigned to the
- * component.
- */
-final class IncompatiblyScopedBindingsValidator implements BindingGraphPlugin {
-
-  private final MethodSignatureFormatter methodSignatureFormatter;
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  IncompatiblyScopedBindingsValidator(
-      MethodSignatureFormatter methodSignatureFormatter, CompilerOptions compilerOptions) {
-    this.methodSignatureFormatter = methodSignatureFormatter;
-    this.compilerOptions = compilerOptions;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/IncompatiblyScopedBindings";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    ImmutableSetMultimap.Builder<ComponentNode, dagger.model.Binding> incompatibleBindings =
-        ImmutableSetMultimap.builder();
-    for (dagger.model.Binding binding : bindingGraph.bindings()) {
-      binding
-          .scope()
-          .filter(scope -> !scope.isReusable())
-          .ifPresent(
-              scope -> {
-                ComponentNode componentNode =
-                    bindingGraph.componentNode(binding.componentPath()).get();
-                if (!componentNode.scopes().contains(scope)) {
-                  // @Inject bindings in module or subcomponent binding graphs will appear at the
-                  // properly scoped ancestor component, so ignore them here.
-                  if (binding.kind().equals(INJECTION)
-                      && (bindingGraph.rootComponentNode().isSubcomponent()
-                          || !bindingGraph.rootComponentNode().isRealComponent())) {
-                    return;
-                  }
-                  incompatibleBindings.put(componentNode, binding);
-                }
-              });
-    }
-    Multimaps.asMap(incompatibleBindings.build())
-        .forEach((componentNode, bindings) -> report(componentNode, bindings, diagnosticReporter));
-  }
-
-  private void report(
-      ComponentNode componentNode,
-      Set<Binding> bindings,
-      DiagnosticReporter diagnosticReporter) {
-    Diagnostic.Kind diagnosticKind = ERROR;
-    StringBuilder message =
-        new StringBuilder(componentNode.componentPath().currentComponent().getQualifiedName());
-
-    if (!componentNode.isRealComponent()) {
-      // If the "component" is really a module, it will have no scopes attached. We want to report
-      // if there is more than one scope in that component.
-      if (bindings.stream().map(Binding::scope).map(Optional::get).distinct().count() <= 1) {
-        return;
-      }
-      message.append(" contains bindings with different scopes:");
-      diagnosticKind = compilerOptions.moduleHasDifferentScopesDiagnosticKind();
-    } else if (componentNode.scopes().isEmpty()) {
-      message.append(" (unscoped) may not reference scoped bindings:");
-    } else {
-      message
-          .append(" scoped with ")
-          .append(
-              componentNode.scopes().stream().map(Scopes::getReadableSource).collect(joining(" ")))
-          .append(" may not reference bindings with different scopes:");
-    }
-
-    // TODO(ronshapiro): Should we group by scope?
-    for (Binding binding : bindings) {
-      message.append('\n').append(INDENT);
-
-      // TODO(dpb): Use BindingDeclarationFormatter.
-      // But that doesn't print scopes for @Inject-constructed types.
-      switch (binding.kind()) {
-        case DELEGATE:
-        case PROVISION:
-          message.append(
-              methodSignatureFormatter.format(
-                  MoreElements.asExecutable(binding.bindingElement().get())));
-          break;
-
-        case INJECTION:
-          message
-              .append(getReadableSource(binding.scope().get()))
-              .append(" class ")
-              .append(
-                  closestEnclosingTypeElement(binding.bindingElement().get()).getQualifiedName());
-          break;
-
-        default:
-          throw new AssertionError(binding);
-      }
-    }
-    diagnosticReporter.reportComponent(diagnosticKind, componentNode, message.toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectBindingRegistry.java b/java/dagger/internal/codegen/InjectBindingRegistry.java
deleted file mode 100644
index 2840d75..0000000
--- a/java/dagger/internal/codegen/InjectBindingRegistry.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.errorprone.annotations.CanIgnoreReturnValue;
-import dagger.Component;
-import dagger.Provides;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * 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.).
- */
-interface InjectBindingRegistry {
-  /**
-   * Returns a {@link ProvisionBinding} for {@code key}. If none has been registered yet, registers
-   * one.
-   */
-  Optional<ProvisionBinding> getOrFindProvisionBinding(Key key);
-
-  /**
-   * 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);
-
-  /**
-   * Returns a {@link ProvisionBinding} for a {@link dagger.MembersInjector} of {@code key}. If none
-   * has been registered yet, registers one.
-   */
-  Optional<ProvisionBinding> getOrFindMembersInjectorProvisionBinding(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;
-}
diff --git a/java/dagger/internal/codegen/InjectBindingRegistryImpl.java b/java/dagger/internal/codegen/InjectBindingRegistryImpl.java
deleted file mode 100644
index 45dc391..0000000
--- a/java/dagger/internal/codegen/InjectBindingRegistryImpl.java
+++ /dev/null
@@ -1,340 +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.Keys.isValidImplicitProvisionKey;
-import static dagger.internal.codegen.Keys.isValidMembersInjectionKey;
-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.MembersInjector;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-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.inject.Provider;
-import javax.inject.Singleton;
-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.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.).
- */
-@Singleton
-final class InjectBindingRegistryImpl implements InjectBindingRegistry {
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-  private final Messager messager;
-  private final InjectValidator injectValidator;
-  private final InjectValidator injectValidatorWhenGeneratingCode;
-  private final KeyFactory keyFactory;
-  private final BindingFactory bindingFactory;
-  private final CompilerOptions compilerOptions;
-
-  final class BindingsCollection<B extends Binding> {
-    private final Class<?> factoryClass;
-    private final Map<Key, B> bindingsByKey = Maps.newLinkedHashMap();
-    private final Deque<B> bindingsRequiringGeneration = new ArrayDeque<>();
-    private final Set<Key> materializedBindingKeys = Sets.newLinkedHashSet();
-
-    BindingsCollection(Class<?> factoryClass) {
-      this.factoryClass = factoryClass;
-    }
-
-    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.",
-                  factoryClass.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()
-          && !materializedBindingKeys.contains(binding.key())
-          && !bindingsRequiringGeneration.contains(binding)
-          && elements.getTypeElement(factoryName) == null;
-    }
-
-    /** 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<>(Provider.class);
-  private final BindingsCollection<MembersInjectionBinding> membersInjectionBindings =
-      new BindingsCollection<>(MembersInjector.class);
-
-  @Inject
-  InjectBindingRegistryImpl(
-      DaggerElements elements,
-      DaggerTypes types,
-      Messager messager,
-      InjectValidator injectValidator,
-      KeyFactory keyFactory,
-      BindingFactory bindingFactory,
-      CompilerOptions compilerOptions) {
-    this.elements = elements;
-    this.types = types;
-    this.messager = messager;
-    this.injectValidator = injectValidator;
-    this.injectValidatorWhenGeneratingCode = injectValidator.whenGeneratingCode();
-    this.keyFactory = keyFactory;
-    this.bindingFactory = bindingFactory;
-    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 = bindingFactory.injectionBinding(constructorElement, resolvedType);
-      registerBinding(binding, warnIfNotAlreadyGenerated);
-      if (!binding.injectionSites().isEmpty()) {
-        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 = bindingFactory.membersInjectionBinding(type, resolvedType);
-      registerBinding(binding, warnIfNotAlreadyGenerated);
-      for (Optional<DeclaredType> supertype = types.nonObjectSuperclass(type);
-          supertype.isPresent();
-          supertype = types.nonObjectSuperclass(supertype.get())) {
-        getOrFindMembersInjectionBinding(keyFactory.forMembersInjectedType(supertype.get()));
-      }
-      return Optional.of(binding);
-    }
-    return Optional.empty();
-  }
-
-  @CanIgnoreReturnValue
-  @Override
-  public Optional<ProvisionBinding> getOrFindProvisionBinding(Key key) {
-    checkNotNull(key);
-    if (!isValidImplicitProvisionKey(key, 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(isValidMembersInjectionKey(key));
-    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;
-  }
-
-  @Override
-  public Optional<ProvisionBinding> getOrFindMembersInjectorProvisionBinding(Key key) {
-    if (!isValidMembersInjectionKey(key)) {
-      return Optional.empty();
-    }
-    Key membersInjectionKey = keyFactory.forMembersInjectedType(types.unwrapType(key.type()));
-    return getOrFindMembersInjectionBinding(membersInjectionKey)
-        .map(binding -> bindingFactory.membersInjectorBinding(key, binding));
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectBindingRegistryModule.java b/java/dagger/internal/codegen/InjectBindingRegistryModule.java
deleted file mode 100644
index 4563362..0000000
--- a/java/dagger/internal/codegen/InjectBindingRegistryModule.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.Binds;
-import dagger.Module;
-
-@Module
-interface InjectBindingRegistryModule {
-  @Binds
-  InjectBindingRegistry injectBindingRegistry(InjectBindingRegistryImpl impl);
-}
diff --git a/java/dagger/internal/codegen/InjectBindingValidator.java b/java/dagger/internal/codegen/InjectBindingValidator.java
deleted file mode 100644
index 183d162..0000000
--- a/java/dagger/internal/codegen/InjectBindingValidator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.model.BindingKind.INJECTION;
-
-import com.google.auto.common.MoreTypes;
-import dagger.internal.codegen.ValidationReport.Item;
-import dagger.model.BindingGraph;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-
-/** Validates bindings from {@code @Inject}-annotated constructors. */
-final class InjectBindingValidator implements BindingGraphPlugin {
-
-  private final InjectValidator injectValidator;
-
-  @Inject
-  InjectBindingValidator(InjectValidator injectValidator) {
-    this.injectValidator = injectValidator.whenGeneratingCode();
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/InjectBinding";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    bindingGraph.bindings().stream()
-        .filter(binding -> binding.kind().equals(INJECTION)) // TODO(dpb): Move to BindingGraph
-        .forEach(binding -> validateInjectionBinding(binding, diagnosticReporter));
-  }
-
-  private void validateInjectionBinding(
-      dagger.model.Binding node, DiagnosticReporter diagnosticReporter) {
-    ValidationReport<TypeElement> typeReport =
-        injectValidator.validateType(MoreTypes.asTypeElement(node.key().type()));
-    for (Item item : typeReport.allItems()) {
-      diagnosticReporter.reportBinding(item.kind(), node, item.message());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectProcessingStep.java b/java/dagger/internal/codegen/InjectProcessingStep.java
deleted file mode 100644
index be8c975..0000000
--- a/java/dagger/internal/codegen/InjectProcessingStep.java
+++ /dev/null
@@ -1,76 +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 com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.ElementKindVisitor8;
-
-/**
- * An annotation processor for generating Dagger implementation code based on the {@link Inject}
- * annotation.
- */
-// TODO(gak): add some error handling for bad source files
-final class InjectProcessingStep extends TypeCheckingProcessingStep<Element> {
-  private final ElementVisitor<Void, Void> visitor;
-
-  @Inject
-  InjectProcessingStep(InjectBindingRegistry injectBindingRegistry) {
-    super(e -> e);
-    this.visitor =
-        new ElementKindVisitor8<Void, Void>() {
-          @Override
-          public Void visitExecutableAsConstructor(
-              ExecutableElement constructorElement, Void aVoid) {
-            injectBindingRegistry.tryRegisterConstructor(constructorElement);
-            return null;
-          }
-
-          @Override
-          public Void visitVariableAsField(VariableElement fieldElement, Void aVoid) {
-            injectBindingRegistry.tryRegisterMembersInjectedType(
-                MoreElements.asType(fieldElement.getEnclosingElement()));
-            return null;
-          }
-
-          @Override
-          public Void visitExecutableAsMethod(ExecutableElement methodElement, Void aVoid) {
-            injectBindingRegistry.tryRegisterMembersInjectedType(
-                MoreElements.asType(methodElement.getEnclosingElement()));
-            return null;
-          }
-        };
-  }
-
-  @Override
-  public Set<Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(Inject.class);
-  }
-
-  @Override
-  protected void process(
-      Element injectElement, ImmutableSet<Class<? extends Annotation>> annotations) {
-    injectElement.accept(visitor, null);
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectValidator.java b/java/dagger/internal/codegen/InjectValidator.java
deleted file mode 100644
index d3c4ce8..0000000
--- a/java/dagger/internal/codegen/InjectValidator.java
+++ /dev/null
@@ -1,332 +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.auto.common.MoreElements.isAnnotationPresent;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifiers;
-import static dagger.internal.codegen.InjectionAnnotations.injectedConstructors;
-import static dagger.internal.codegen.Scopes.scopesOf;
-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.STATIC;
-import static javax.lang.model.type.TypeKind.DECLARED;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.internal.codegen.langmodel.Accessibility;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Scope;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-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.lang.model.util.ElementFilter;
-import javax.tools.Diagnostic;
-import javax.tools.Diagnostic.Kind;
-
-/**
- * A {@linkplain ValidationReport validator} for {@link Inject}-annotated elements and the types
- * that contain them.
- */
-final class InjectValidator {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final CompilerOptions compilerOptions;
-  private final DependencyRequestValidator dependencyRequestValidator;
-  private final Optional<Diagnostic.Kind> privateAndStaticInjectionDiagnosticKind;
-
-  @Inject
-  InjectValidator(
-      DaggerTypes types,
-      DaggerElements elements,
-      DependencyRequestValidator dependencyRequestValidator,
-      CompilerOptions compilerOptions) {
-    this(types, elements, compilerOptions, dependencyRequestValidator, Optional.empty());
-  }
-
-  private InjectValidator(
-      DaggerTypes types,
-      DaggerElements elements,
-      CompilerOptions compilerOptions,
-      DependencyRequestValidator dependencyRequestValidator,
-      Optional<Kind> privateAndStaticInjectionDiagnosticKind) {
-    this.types = types;
-    this.elements = elements;
-    this.compilerOptions = compilerOptions;
-    this.dependencyRequestValidator = dependencyRequestValidator;
-    this.privateAndStaticInjectionDiagnosticKind = privateAndStaticInjectionDiagnosticKind;
-  }
-
-  /**
-   * Returns a new validator that performs the same validation as this one, but is strict about
-   * rejecting optionally-specified JSR 330 behavior that Dagger doesn't support (unless {@code
-   * -Adagger.ignorePrivateAndStaticInjectionForComponent=enabled} was set in the javac options).
-   */
-  InjectValidator whenGeneratingCode() {
-    return compilerOptions.ignorePrivateAndStaticInjectionForComponent()
-        ? this
-        : new InjectValidator(
-            types,
-            elements,
-            compilerOptions,
-            dependencyRequestValidator,
-            Optional.of(Diagnostic.Kind.ERROR));
-  }
-
-  ValidationReport<TypeElement> validateConstructor(ExecutableElement constructorElement) {
-    ValidationReport.Builder<TypeElement> builder =
-        ValidationReport.about(MoreElements.asType(constructorElement.getEnclosingElement()));
-    if (constructorElement.getModifiers().contains(PRIVATE)) {
-      builder.addError(
-          "Dagger does not support injection into private constructors", constructorElement);
-    }
-
-    for (AnnotationMirror qualifier : getQualifiers(constructorElement)) {
-      builder.addError(
-          "@Qualifier annotations are not allowed on @Inject constructors",
-          constructorElement,
-          qualifier);
-    }
-
-    for (Scope scope : scopesOf(constructorElement)) {
-      builder.addError(
-          "@Scope annotations are not allowed on @Inject constructors; annotate the class instead",
-          constructorElement,
-          scope.scopeAnnotation());
-    }
-
-    for (VariableElement parameter : constructorElement.getParameters()) {
-      validateDependencyRequest(builder, parameter);
-    }
-
-    if (throwsCheckedExceptions(constructorElement)) {
-      builder.addItem(
-          "Dagger does not support checked exceptions on @Inject constructors",
-          privateMemberDiagnosticKind(),
-          constructorElement);
-    }
-
-    checkInjectIntoPrivateClass(constructorElement, builder);
-
-    TypeElement enclosingElement =
-        MoreElements.asType(constructorElement.getEnclosingElement());
-
-    Set<Modifier> typeModifiers = enclosingElement.getModifiers();
-    if (typeModifiers.contains(ABSTRACT)) {
-      builder.addError(
-          "@Inject is nonsense on the constructor of an abstract class", constructorElement);
-    }
-
-    if (enclosingElement.getNestingKind().isNested()
-        && !typeModifiers.contains(STATIC)) {
-      builder.addError(
-          "@Inject constructors are invalid on inner classes. "
-              + "Did you mean to make the class static?",
-          constructorElement);
-    }
-
-    // This is computationally expensive, but probably preferable to a giant index
-    ImmutableSet<ExecutableElement> injectConstructors = injectedConstructors(enclosingElement);
-
-    if (injectConstructors.size() > 1) {
-      builder.addError("Types may only contain one @Inject constructor", constructorElement);
-    }
-
-    ImmutableSet<Scope> scopes = scopesOf(enclosingElement);
-    if (scopes.size() > 1) {
-      for (Scope scope : scopes) {
-        builder.addError(
-            "A single binding may not declare more than one @Scope",
-            enclosingElement,
-            scope.scopeAnnotation());
-      }
-    }
-
-    return builder.build();
-  }
-
-  private ValidationReport<VariableElement> validateField(VariableElement fieldElement) {
-    ValidationReport.Builder<VariableElement> builder = ValidationReport.about(fieldElement);
-    Set<Modifier> modifiers = fieldElement.getModifiers();
-    if (modifiers.contains(FINAL)) {
-      builder.addError("@Inject fields may not be final", fieldElement);
-    }
-
-    if (modifiers.contains(PRIVATE)) {
-      builder.addItem(
-          "Dagger does not support injection into private fields",
-          privateMemberDiagnosticKind(),
-          fieldElement);
-    }
-
-    if (modifiers.contains(STATIC)) {
-      builder.addItem(
-          "Dagger does not support injection into static fields",
-          staticMemberDiagnosticKind(),
-          fieldElement);
-    }
-
-    validateDependencyRequest(builder, fieldElement);
-
-    return builder.build();
-  }
-
-  private ValidationReport<ExecutableElement> validateMethod(ExecutableElement methodElement) {
-    ValidationReport.Builder<ExecutableElement> builder = ValidationReport.about(methodElement);
-    Set<Modifier> modifiers = methodElement.getModifiers();
-    if (modifiers.contains(ABSTRACT)) {
-      builder.addError("Methods with @Inject may not be abstract", methodElement);
-    }
-
-    if (modifiers.contains(PRIVATE)) {
-      builder.addItem(
-          "Dagger does not support injection into private methods",
-          privateMemberDiagnosticKind(),
-          methodElement);
-    }
-
-    if (modifiers.contains(STATIC)) {
-      builder.addItem(
-          "Dagger does not support injection into static methods",
-          staticMemberDiagnosticKind(),
-          methodElement);
-    }
-
-    if (!methodElement.getTypeParameters().isEmpty()) {
-      builder.addError("Methods with @Inject may not declare type parameters", methodElement);
-    }
-
-    for (VariableElement parameter : methodElement.getParameters()) {
-      validateDependencyRequest(builder, parameter);
-    }
-
-    return builder.build();
-  }
-
-  private void validateDependencyRequest(
-      ValidationReport.Builder<?> builder, VariableElement parameter) {
-    dependencyRequestValidator.validateDependencyRequest(builder, parameter, parameter.asType());
-    dependencyRequestValidator.checkNotProducer(builder, parameter);
-  }
-
-  ValidationReport<TypeElement> validateMembersInjectionType(TypeElement typeElement) {
-    // TODO(beder): This element might not be currently compiled, so this error message could be
-    // left in limbo. Find an appropriate way to display the error message in that case.
-    ValidationReport.Builder<TypeElement> builder = ValidationReport.about(typeElement);
-    boolean hasInjectedMembers = false;
-    for (VariableElement element : ElementFilter.fieldsIn(typeElement.getEnclosedElements())) {
-      if (MoreElements.isAnnotationPresent(element, Inject.class)) {
-        hasInjectedMembers = true;
-        ValidationReport<VariableElement> report = validateField(element);
-        if (!report.isClean()) {
-          builder.addSubreport(report);
-        }
-      }
-    }
-    for (ExecutableElement element : ElementFilter.methodsIn(typeElement.getEnclosedElements())) {
-      if (MoreElements.isAnnotationPresent(element, Inject.class)) {
-        hasInjectedMembers = true;
-        ValidationReport<ExecutableElement> report = validateMethod(element);
-        if (!report.isClean()) {
-          builder.addSubreport(report);
-        }
-      }
-    }
-
-    if (hasInjectedMembers) {
-      checkInjectIntoPrivateClass(typeElement, builder);
-    }
-    TypeMirror superclass = typeElement.getSuperclass();
-    if (!superclass.getKind().equals(TypeKind.NONE)) {
-      ValidationReport<TypeElement> report = validateType(MoreTypes.asTypeElement(superclass));
-      if (!report.isClean()) {
-        builder.addSubreport(report);
-      }
-    }
-    return builder.build();
-  }
-
-  ValidationReport<TypeElement> validateType(TypeElement typeElement) {
-    ValidationReport.Builder<TypeElement> builder = ValidationReport.about(typeElement);
-    ValidationReport<TypeElement> membersInjectionReport =
-        validateMembersInjectionType(typeElement);
-    if (!membersInjectionReport.isClean()) {
-      builder.addSubreport(membersInjectionReport);
-    }
-    for (ExecutableElement element :
-        ElementFilter.constructorsIn(typeElement.getEnclosedElements())) {
-      if (isAnnotationPresent(element, Inject.class)) {
-        ValidationReport<TypeElement> report = validateConstructor(element);
-        if (!report.isClean()) {
-          builder.addSubreport(report);
-        }
-      }
-    }
-    return builder.build();
-  }
-
-  boolean isValidType(TypeMirror type) {
-    if (!type.getKind().equals(DECLARED)) {
-      return true;
-    }
-    return validateType(MoreTypes.asTypeElement(type)).isClean();
-  }
-
-  /** Returns true if the given method element declares a checked exception. */
-  private boolean throwsCheckedExceptions(ExecutableElement methodElement) {
-    TypeMirror runtimeExceptionType = elements.getTypeElement(RuntimeException.class).asType();
-    TypeMirror errorType = elements.getTypeElement(Error.class).asType();
-    for (TypeMirror thrownType : methodElement.getThrownTypes()) {
-      if (!types.isSubtype(thrownType, runtimeExceptionType)
-          && !types.isSubtype(thrownType, errorType)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private void checkInjectIntoPrivateClass(
-      Element element, ValidationReport.Builder<TypeElement> builder) {
-    if (!Accessibility.isElementAccessibleFromOwnPackage(
-        DaggerElements.closestEnclosingTypeElement(element))) {
-      builder.addItem(
-          "Dagger does not support injection into private classes",
-          privateMemberDiagnosticKind(),
-          element);
-    }
-  }
-
-  private Diagnostic.Kind privateMemberDiagnosticKind() {
-    return privateAndStaticInjectionDiagnosticKind.orElse(
-        compilerOptions.privateMemberValidationKind());
-  }
-
-  private Diagnostic.Kind staticMemberDiagnosticKind() {
-    return privateAndStaticInjectionDiagnosticKind.orElse(
-        compilerOptions.staticMemberValidationKind());
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectionAnnotations.java b/java/dagger/internal/codegen/InjectionAnnotations.java
deleted file mode 100644
index 521ad43..0000000
--- a/java/dagger/internal/codegen/InjectionAnnotations.java
+++ /dev/null
@@ -1,68 +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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static javax.lang.model.util.ElementFilter.constructorsIn;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.auto.common.SuperficialValidation;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Utilities relating to annotations defined in the {@code javax.inject} package.
- */
-final class InjectionAnnotations {
-  static Optional<AnnotationMirror> getQualifier(Element e) {
-    if (!SuperficialValidation.validateElement(e)) {
-      throw new TypeNotPresentException(e.toString(), null);
-    }
-    checkNotNull(e);
-    ImmutableSet<? extends AnnotationMirror> qualifierAnnotations = getQualifiers(e);
-    switch (qualifierAnnotations.size()) {
-      case 0:
-        return Optional.empty();
-      case 1:
-        return Optional.<AnnotationMirror>of(qualifierAnnotations.iterator().next());
-      default:
-        throw new IllegalArgumentException(
-            e + " was annotated with more than one @Qualifier annotation");
-    }
-  }
-
-  static ImmutableSet<? extends AnnotationMirror> getQualifiers(Element element) {
-    return AnnotationMirrors.getAnnotatedAnnotations(element, Qualifier.class);
-  }
-
-  /** Returns the constructors in {@code type} that are annotated with {@link Inject}. */
-  static ImmutableSet<ExecutableElement> injectedConstructors(TypeElement type) {
-    return FluentIterable.from(constructorsIn(type.getEnclosedElements()))
-        .filter(constructor -> isAnnotationPresent(constructor, Inject.class))
-        .toSet();
-  }
-
-  private InjectionAnnotations() {}
-}
diff --git a/java/dagger/internal/codegen/InjectionMethod.java b/java/dagger/internal/codegen/InjectionMethod.java
deleted file mode 100644
index 2785b18..0000000
--- a/java/dagger/internal/codegen/InjectionMethod.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2018 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.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
-import static dagger.internal.codegen.langmodel.Accessibility.isRawTypePubliclyAccessible;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.List;
-import java.util.Optional;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Parameterizable;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A static method that implements provision and/or injection in one step:
- *
- * <ul>
- *   <li>methods that invoke {@code @Inject} constructors and do members injection if necessary
- *   <li>methods that call {@code @Provides} module methods
- *   <li>methods that perform members injection
- * </ul>
- *
- * <p>Note that although this type uses {@code @AutoValue}, it uses instance equality. It uses
- * {@code @AutoValue} to avoid the boilerplate of writing a correct builder, but is not intended to
- * actually be a value type.
- */
-@AutoValue
-abstract class InjectionMethod {
-  abstract String name();
-
-  abstract boolean varargs();
-
-  abstract ImmutableList<TypeVariableName> typeVariables();
-
-  abstract ImmutableMap<ParameterSpec, TypeMirror> parameters();
-
-  abstract Optional<TypeMirror> returnType();
-
-  abstract Optional<DeclaredType> nullableAnnotation();
-
-  abstract ImmutableList<TypeMirror> exceptions();
-
-  abstract CodeBlock methodBody();
-
-  abstract ClassName enclosingClass();
-
-  MethodSpec toMethodSpec() {
-    MethodSpec.Builder builder =
-        methodBuilder(name())
-            .addModifiers(PUBLIC, STATIC)
-            .varargs(varargs())
-            .addTypeVariables(typeVariables())
-            .addParameters(parameters().keySet())
-            .addCode(methodBody());
-    returnType().map(TypeName::get).ifPresent(builder::returns);
-    nullableAnnotation()
-        .ifPresent(nullableType -> CodeBlocks.addAnnotation(builder, nullableType));
-    exceptions().stream().map(TypeName::get).forEach(builder::addException);
-    return builder.build();
-  }
-
-  CodeBlock invoke(List<CodeBlock> arguments, ClassName requestingClass) {
-    checkArgument(arguments.size() == parameters().size());
-    CodeBlock.Builder invocation = CodeBlock.builder();
-    if (!enclosingClass().equals(requestingClass)) {
-      invocation.add("$T.", enclosingClass());
-    }
-    return invocation.add("$L($L)", name(), makeParametersCodeBlock(arguments)).build();
-  }
-
-  @Override
-  public final int hashCode() {
-    return System.identityHashCode(this);
-  }
-
-  @Override
-  public final boolean equals(Object obj) {
-    return this == obj;
-  }
-
-  static Builder builder(DaggerElements elements) {
-    Builder builder = new AutoValue_InjectionMethod.Builder();
-    builder.elements = elements;
-    builder.varargs(false).exceptions(ImmutableList.of()).nullableAnnotation(Optional.empty());
-    return builder;
-  }
-
-  @CanIgnoreReturnValue
-  @AutoValue.Builder
-  abstract static class Builder {
-    private final UniqueNameSet parameterNames = new UniqueNameSet();
-    private final CodeBlock.Builder methodBody = CodeBlock.builder();
-    private DaggerElements elements;
-
-    abstract ImmutableMap.Builder<ParameterSpec, TypeMirror> parametersBuilder();
-    abstract ImmutableList.Builder<TypeVariableName> typeVariablesBuilder();
-    abstract Builder name(String name);
-    abstract Builder varargs(boolean varargs);
-    abstract Builder returnType(TypeMirror returnType);
-    abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions);
-    abstract Builder nullableAnnotation(Optional<DeclaredType> nullableAnnotation);
-    abstract Builder methodBody(CodeBlock methodBody);
-
-    final CodeBlock.Builder methodBodyBuilder() {
-      return methodBody;
-    }
-
-    abstract Builder enclosingClass(ClassName enclosingClass);
-
-    /**
-     * Adds a parameter for the given name and type. If another parameter has already been added
-     * with the same name, the name is disambiguated.
-     */
-    ParameterSpec addParameter(String name, TypeMirror type) {
-      ParameterSpec parameter =
-          ParameterSpec.builder(TypeName.get(type), parameterNames.getUniqueName(name)).build();
-      parametersBuilder().put(parameter, type);
-      return parameter;
-    }
-
-    /**
-     * Calls {@link #copyParameter(VariableElement)} for each parameter of of {@code method}, and
-     * concatenates the results of each call, {@link CodeBlocks#makeParametersCodeBlock(Iterable)
-     * separated with commas}.
-     */
-    CodeBlock copyParameters(ExecutableElement method) {
-      ImmutableList.Builder<CodeBlock> argumentsBuilder = ImmutableList.builder();
-      for (VariableElement parameter : method.getParameters()) {
-        argumentsBuilder.add(copyParameter(parameter));
-      }
-      varargs(method.isVarArgs());
-      return makeParametersCodeBlock(argumentsBuilder.build());
-    }
-
-    /**
-     * Adds {@code parameter} as a parameter of this method, using a publicly accessible version of
-     * the parameter's type. Returns a {@link CodeBlock} of the usage of this parameter within the
-     * injection method's {@link #methodBody()}.
-     */
-    CodeBlock copyParameter(VariableElement parameter) {
-      TypeMirror elementType = parameter.asType();
-      boolean useObject = !isRawTypePubliclyAccessible(elementType);
-      TypeMirror publicType =  useObject ? objectType() : elementType;
-      ParameterSpec parameterSpec = addParameter(parameter.getSimpleName().toString(), publicType);
-      return useObject
-          ? CodeBlock.of("($T) $N", elementType, parameterSpec)
-          : CodeBlock.of("$N", parameterSpec);
-    }
-
-    private TypeMirror objectType() {
-      return elements.getTypeElement(Object.class).asType();
-    }
-
-    /**
-     * Adds each type parameter of {@code parameterizable} as a type parameter of this injection
-     * method.
-     */
-    Builder copyTypeParameters(Parameterizable parameterizable) {
-      parameterizable.getTypeParameters().stream()
-          .map(TypeVariableName::get)
-          .forEach(typeVariablesBuilder()::add);
-      return this;
-    }
-
-    Builder copyThrows(ExecutableElement element) {
-      exceptions(element.getThrownTypes());
-      return this;
-    }
-
-    @CheckReturnValue
-    final InjectionMethod build() {
-      return methodBody(methodBody.build()).buildInternal();
-    }
-
-    abstract InjectionMethod buildInternal();
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectionMethods.java b/java/dagger/internal/codegen/InjectionMethods.java
deleted file mode 100644
index d61aaa5..0000000
--- a/java/dagger/internal/codegen/InjectionMethods.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 2017 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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.Preconditions.checkArgument;
-import static dagger.internal.codegen.ConfigurationAnnotations.getNullableType;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.FactoryGenerator.checkNotNullProvidesMethod;
-import static dagger.internal.codegen.RequestKinds.requestTypeName;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toConcatenatedCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName;
-import static dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom;
-import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible;
-import static dagger.internal.codegen.langmodel.Accessibility.isRawTypePubliclyAccessible;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static java.util.stream.Collectors.toList;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.type.TypeKind.VOID;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import dagger.model.RequestKind;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-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;
-
-/** Convenience methods for creating and invoking {@link InjectionMethod}s. */
-final class InjectionMethods {
-
-  /**
-   * A method that returns an object from a {@code @Provides} method or an {@code @Inject}ed
-   * constructor. Its parameters match the dependency requests for constructor and members
-   * injection.
-   *
-   * <p>For {@code @Provides} methods named "foo", the method name is "proxyFoo". If the
-   * {@code @Provides} method and its raw parameter types are publicly accessible, no method is
-   * necessary and this method returns {@link Optional#empty()}.
-   *
-   * <p>Example:
-   *
-   * <pre><code>
-   * abstract class FooModule {
-   *   {@literal @Provides} static Foo provideFoo(Bar bar, Baz baz) { … }
-   * }
-   *
-   * public static proxyProvideFoo(Bar bar, Baz baz) { … }
-   * </code></pre>
-   *
-   * <p>For {@code @Inject}ed constructors, the method name is "newFoo". If the constructor and its
-   * raw parameter types are publicly accessible, no method is necessary and this method returns
-   * {@code Optional#empty()}.
-   *
-   * <p>Example:
-   *
-   * <pre><code>
-   * class Foo {
-   *   {@literal @Inject} Foo(Bar bar) {}
-   * }
-   *
-   * public static Foo newFoo(Bar bar) { … }
-   * </code></pre>
-   */
-  static final class ProvisionMethod {
-    /**
-     * Names of methods that are already defined in factories and shouldn't be used for the proxy
-     * method name.
-     */
-    private static final ImmutableSet<String> BANNED_PROXY_NAMES = ImmutableSet.of("get", "create");
-
-    /**
-     * Returns a method that invokes the binding's {@linkplain ProvisionBinding#bindingElement()
-     * constructor} and injects the instance's members.
-     */
-    static InjectionMethod create(
-        ProvisionBinding binding, CompilerOptions compilerOptions, DaggerElements elements) {
-      ClassName proxyEnclosingClass = generatedClassNameForBinding(binding);
-      ExecutableElement element = MoreElements.asExecutable(binding.bindingElement().get());
-      switch (element.getKind()) {
-        case CONSTRUCTOR:
-          return constructorProxy(proxyEnclosingClass, element, elements);
-        case METHOD:
-          return methodProxy(
-              proxyEnclosingClass,
-              element,
-              methodName(element),
-              ReceiverAccessibility.IGNORE,
-              CheckNotNullPolicy.get(binding, compilerOptions),
-              elements);
-        default:
-          throw new AssertionError(element);
-      }
-    }
-
-    /**
-     * Invokes the injection method for {@code binding}, with the dependencies transformed with the
-     * {@code dependencyUsage} function.
-     */
-    // TODO(ronshapiro): Further extract a ProvisionMethod type that composes an InjectionMethod, so
-    // users can write ProvisionMethod.create().invoke()
-    static CodeBlock invoke(
-        ProvisionBinding binding,
-        Function<DependencyRequest, CodeBlock> dependencyUsage,
-        ClassName requestingClass,
-        Optional<CodeBlock> moduleReference,
-        CompilerOptions compilerOptions,
-        DaggerElements elements) {
-      ImmutableList.Builder<CodeBlock> arguments = ImmutableList.builder();
-      moduleReference.ifPresent(arguments::add);
-      arguments.addAll(
-          injectionMethodArguments(
-              binding.provisionDependencies(), dependencyUsage, requestingClass));
-      // TODO(ronshapiro): make InjectionMethods @Injectable
-      return create(binding, compilerOptions, elements).invoke(arguments.build(), requestingClass);
-    }
-
-    private static InjectionMethod constructorProxy(
-        ClassName proxyEnclosingClass, ExecutableElement constructor, DaggerElements elements) {
-      TypeElement enclosingType = MoreElements.asType(constructor.getEnclosingElement());
-      InjectionMethod.Builder injectionMethod =
-          InjectionMethod.builder(elements)
-              .name(methodName(constructor))
-              .returnType(enclosingType.asType())
-              .enclosingClass(proxyEnclosingClass);
-
-      injectionMethod
-          .copyTypeParameters(enclosingType)
-          .copyThrows(constructor);
-
-      CodeBlock arguments = injectionMethod.copyParameters(constructor);
-      injectionMethod
-          .methodBodyBuilder()
-          .addStatement("return new $T($L)", enclosingType, arguments);
-      return injectionMethod.build();
-    }
-
-    /**
-     * Returns {@code true} if injecting an instance of {@code binding} from {@code callingPackage}
-     * requires the use of an injection method.
-     */
-    static boolean requiresInjectionMethod(
-        ProvisionBinding binding,
-        ImmutableList<Expression> arguments,
-        CompilerOptions compilerOptions,
-        String callingPackage,
-        DaggerTypes types) {
-      ExecutableElement method = MoreElements.asExecutable(binding.bindingElement().get());
-      return !binding.injectionSites().isEmpty()
-          || binding.shouldCheckForNull(compilerOptions)
-          || !isElementAccessibleFrom(method, callingPackage)
-          || !areParametersAssignable(method, arguments, types)
-          // This check should be removable once we drop support for -source 7
-          || method.getParameters().stream()
-              .map(VariableElement::asType)
-              .anyMatch(type -> !isRawTypeAccessible(type, callingPackage));
-    }
-
-    private static boolean areParametersAssignable(
-        ExecutableElement element, ImmutableList<Expression> arguments, DaggerTypes types) {
-      List<? extends VariableElement> parameters = element.getParameters();
-      checkArgument(parameters.size() == arguments.size());
-      for (int i = 0; i < parameters.size(); i++) {
-        if (!types.isAssignable(arguments.get(i).type(), parameters.get(i).asType())) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /**
-     * Returns the name of the {@code static} method that wraps {@code method}. For methods that are
-     * associated with {@code @Inject} constructors, the method will also inject all {@link
-     * InjectionSite}s.
-     */
-    private static String methodName(ExecutableElement method) {
-      switch (method.getKind()) {
-        case CONSTRUCTOR:
-          return "newInstance";
-        case METHOD:
-          String methodName = method.getSimpleName().toString();
-          return BANNED_PROXY_NAMES.contains(methodName)
-              ? "proxy" + LOWER_CAMEL.to(UPPER_CAMEL, methodName)
-              : methodName;
-        default:
-          throw new AssertionError(method);
-      }
-    }
-  }
-
-  /**
-   * A static method that injects one member of an instance of a type. Its first parameter is an
-   * instance of the type to be injected. The remaining parameters match the dependency requests for
-   * the injection site.
-   *
-   * <p>Example:
-   *
-   * <pre><code>
-   * class Foo {
-   *   {@literal @Inject} Bar bar;
-   *   {@literal @Inject} void setThings(Baz baz, Qux qux) {}
-   * }
-   *
-   * public static injectBar(Foo instance, Bar bar) { … }
-   * public static injectSetThings(Foo instance, Baz baz, Qux qux) { … }
-   * </code></pre>
-   */
-  static final class InjectionSiteMethod {
-    /**
-     * When a type has an inaccessible member from a supertype (e.g. an @Inject field in a parent
-     * that's in a different package), a method in the supertype's package must be generated to give
-     * the subclass's members injector a way to inject it. Each potentially inaccessible member
-     * receives its own method, as the subclass may need to inject them in a different order from
-     * the parent class.
-     */
-    static InjectionMethod create(InjectionSite injectionSite, DaggerElements elements) {
-      String methodName = methodName(injectionSite);
-      ClassName proxyEnclosingClass = membersInjectorNameForType(
-          MoreElements.asType(injectionSite.element().getEnclosingElement()));
-      switch (injectionSite.kind()) {
-        case METHOD:
-          return methodProxy(
-              proxyEnclosingClass,
-              MoreElements.asExecutable(injectionSite.element()),
-              methodName,
-              ReceiverAccessibility.CAST_IF_NOT_PUBLIC,
-              CheckNotNullPolicy.IGNORE,
-              elements);
-        case FIELD:
-          return fieldProxy(
-              proxyEnclosingClass,
-              MoreElements.asVariable(injectionSite.element()),
-              methodName,
-              elements);
-      }
-      throw new AssertionError(injectionSite);
-    }
-
-    /**
-     * Invokes each of the injection methods for {@code injectionSites}, with the dependencies
-     * transformed using the {@code dependencyUsage} function.
-     *
-     * @param instanceType the type of the {@code instance} parameter
-     */
-    static CodeBlock invokeAll(
-        ImmutableSet<InjectionSite> injectionSites,
-        ClassName generatedTypeName,
-        CodeBlock instanceCodeBlock,
-        TypeMirror instanceType,
-        DaggerTypes types,
-        Function<DependencyRequest, CodeBlock> dependencyUsage,
-        DaggerElements elements) {
-      return injectionSites
-          .stream()
-          .map(
-              injectionSite -> {
-                TypeMirror injectSiteType =
-                    types.erasure(injectionSite.element().getEnclosingElement().asType());
-
-                // If instance has been declared as Object because it is not accessible from the
-                // component, but the injectionSite is in a supertype of instanceType that is
-                // publicly accessible, the InjectionSiteMethod will request the actual type and not
-                // Object as the first parameter. If so, cast to the supertype which is accessible
-                // from within generatedTypeName
-                CodeBlock maybeCastedInstance =
-                    !types.isSubtype(instanceType, injectSiteType)
-                            && isTypeAccessibleFrom(injectSiteType, generatedTypeName.packageName())
-                        ? CodeBlock.of("($T) $L", injectSiteType, instanceCodeBlock)
-                        : instanceCodeBlock;
-                return CodeBlock.of(
-                    "$L;",
-                    invoke(
-                        injectionSite,
-                        generatedTypeName,
-                        maybeCastedInstance,
-                        dependencyUsage,
-                        elements));
-              })
-          .collect(toConcatenatedCodeBlock());
-    }
-
-    /**
-     * Invokes the injection method for {@code injectionSite}, with the dependencies transformed
-     * using the {@code dependencyUsage} function.
-     */
-    private static CodeBlock invoke(
-        InjectionSite injectionSite,
-        ClassName generatedTypeName,
-        CodeBlock instanceCodeBlock,
-        Function<DependencyRequest, CodeBlock> dependencyUsage,
-        DaggerElements elements) {
-      List<CodeBlock> arguments = new ArrayList<>();
-      arguments.add(instanceCodeBlock);
-      if (!injectionSite.dependencies().isEmpty()) {
-        arguments.addAll(
-            injectionSite
-                .dependencies()
-                .stream()
-                .map(dependencyUsage)
-                .collect(toList()));
-      }
-      return create(injectionSite, elements).invoke(arguments, generatedTypeName);
-    }
-
-    /*
-     * TODO(ronshapiro): this isn't perfect, as collisions could still exist. Some examples:
-     *
-     *  - @Inject void members() {} will generate a method that conflicts with the instance
-     *    method `injectMembers(T)`
-     *  - Adding the index could conflict with another member:
-     *      @Inject void a(Object o) {}
-     *      @Inject void a(String s) {}
-     *      @Inject void a1(String s) {}
-     *
-     *    Here, Method a(String) will add the suffix "1", which will conflict with the method
-     *    generated for a1(String)
-     *  - Members named "members" or "methods" could also conflict with the {@code static} injection
-     *    method.
-     */
-    private static String methodName(InjectionSite injectionSite) {
-      int index = injectionSite.indexAmongAtInjectMembersWithSameSimpleName();
-      String indexString = index == 0 ? "" : String.valueOf(index + 1);
-      return "inject"
-          + LOWER_CAMEL.to(UPPER_CAMEL, injectionSite.element().getSimpleName().toString())
-          + indexString;
-    }
-  }
-
-  /**
-   * Returns an argument list suitable for calling an injection method. Down-casts any arguments
-   * that are {@code Object} (or {@code Provider<Object>}) at the caller but not the method.
-   *
-   * @param dependencies the dependencies used by the method
-   * @param dependencyUsage function to apply on each of {@code dependencies} before casting
-   * @param requestingClass the class calling the injection method
-   */
-  private static ImmutableList<CodeBlock> injectionMethodArguments(
-      ImmutableSet<DependencyRequest> dependencies,
-      Function<DependencyRequest, CodeBlock> dependencyUsage,
-      ClassName requestingClass) {
-    return dependencies.stream()
-        .map(dep -> injectionMethodArgument(dep, dependencyUsage.apply(dep), requestingClass))
-        .collect(toImmutableList());
-  }
-
-  private static CodeBlock injectionMethodArgument(
-      DependencyRequest dependency, CodeBlock argument, ClassName generatedTypeName) {
-    TypeMirror keyType = dependency.key().type();
-    CodeBlock.Builder codeBlock = CodeBlock.builder();
-    if (!isRawTypeAccessible(keyType, generatedTypeName.packageName())
-        && isTypeAccessibleFrom(keyType, generatedTypeName.packageName())) {
-      if (!dependency.kind().equals(RequestKind.INSTANCE)) {
-        TypeName usageTypeName = accessibleType(dependency);
-        codeBlock.add("($T) ($T)", usageTypeName, rawTypeName(usageTypeName));
-      } else if (dependency.requestElement().get().asType().getKind().equals(TypeKind.TYPEVAR)) {
-        codeBlock.add("($T)", keyType);
-      }
-    }
-    return codeBlock.add(argument).build();
-  }
-
-  /**
-   * Returns the parameter type for {@code dependency}. If the raw type is not accessible, returns
-   * {@link Object}.
-   */
-  private static TypeName accessibleType(DependencyRequest dependency) {
-    TypeName typeName = requestTypeName(dependency.kind(), accessibleType(dependency.key().type()));
-    return dependency
-            .requestElement()
-            .map(element -> element.asType().getKind().isPrimitive())
-            .orElse(false)
-        ? typeName.unbox()
-        : typeName;
-  }
-
-  /**
-   * Returns the accessible type for {@code type}. If the raw type is not accessible, returns {@link
-   * Object}.
-   */
-  private static TypeName accessibleType(TypeMirror type) {
-    return isRawTypePubliclyAccessible(type) ? TypeName.get(type) : TypeName.OBJECT;
-  }
-
-  /**
-   * Returns the accessible type for {@code type}. If the raw type is not accessible, returns {@link
-   * Object}.
-   */
-  // TODO(ronshapiro): Can we use DaggerTypes.publiclyAccessibleType in place of this method?
-  private static TypeMirror accessibleType(TypeMirror type, DaggerElements elements) {
-    return isRawTypePubliclyAccessible(type)
-        ? type
-        : elements.getTypeElement(Object.class).asType();
-  }
-
-  private enum ReceiverAccessibility {
-    CAST_IF_NOT_PUBLIC {
-      @Override
-      TypeMirror parameterType(TypeMirror type, DaggerElements elements) {
-        return accessibleType(type, elements);
-      }
-
-      @Override
-      CodeBlock potentiallyCast(CodeBlock instance, TypeMirror instanceType) {
-        return instanceWithPotentialCast(instance, instanceType);
-      }
-    },
-    IGNORE {
-      @Override
-      TypeMirror parameterType(TypeMirror type, DaggerElements elements) {
-        return type;
-      }
-
-      @Override
-      CodeBlock potentiallyCast(CodeBlock instance, TypeMirror instanceType) {
-        return instance;
-      }
-    },
-    ;
-
-    abstract TypeMirror parameterType(TypeMirror type, DaggerElements elements);
-    abstract CodeBlock potentiallyCast(CodeBlock instance, TypeMirror instanceType);
-  }
-
-  private static CodeBlock instanceWithPotentialCast(CodeBlock instance, TypeMirror instanceType) {
-    return isRawTypePubliclyAccessible(instanceType)
-        ? instance
-        : CodeBlock.of("(($T) $L)", instanceType, instance);
-  }
-
-  private enum CheckNotNullPolicy {
-    IGNORE, CHECK_FOR_NULL;
-    CodeBlock checkForNull(CodeBlock maybeNull) {
-      if (this.equals(IGNORE)) {
-        return maybeNull;
-      }
-      return checkNotNullProvidesMethod(maybeNull);
-    }
-
-    static CheckNotNullPolicy get(ProvisionBinding binding, CompilerOptions compilerOptions) {
-      return binding.shouldCheckForNull(compilerOptions) ? CHECK_FOR_NULL : IGNORE;
-    }
-  }
-
-  private static InjectionMethod methodProxy(
-      ClassName proxyEnclosingClass,
-      ExecutableElement method,
-      String methodName,
-      ReceiverAccessibility receiverAccessibility,
-      CheckNotNullPolicy checkNotNullPolicy,
-      DaggerElements elements) {
-    TypeElement enclosingType = MoreElements.asType(method.getEnclosingElement());
-    InjectionMethod.Builder injectionMethod =
-        InjectionMethod.builder(elements).name(methodName).enclosingClass(proxyEnclosingClass);
-    ParameterSpec instance = null;
-    if (!method.getModifiers().contains(STATIC)) {
-      instance =
-          injectionMethod.addParameter(
-              "instance", receiverAccessibility.parameterType(enclosingType.asType(), elements));
-    }
-
-    CodeBlock arguments = injectionMethod.copyParameters(method);
-    if (!method.getReturnType().getKind().equals(VOID)) {
-      injectionMethod
-          .returnType(method.getReturnType())
-          .nullableAnnotation(getNullableType(method));
-      injectionMethod.methodBodyBuilder().add("return ");
-    }
-    CodeBlock.Builder proxyInvocation = CodeBlock.builder();
-    if (method.getModifiers().contains(STATIC)) {
-      proxyInvocation.add("$T", rawTypeName(TypeName.get(enclosingType.asType())));
-    } else {
-      injectionMethod.copyTypeParameters(enclosingType);
-      proxyInvocation.add(
-          receiverAccessibility.potentiallyCast(
-              CodeBlock.of("$N", instance), enclosingType.asType()));
-    }
-
-    injectionMethod
-        .copyTypeParameters(method)
-        .copyThrows(method);
-
-    proxyInvocation.add(".$N($L)", method.getSimpleName(), arguments);
-    injectionMethod
-        .methodBodyBuilder()
-        .add(checkNotNullPolicy.checkForNull(proxyInvocation.build()))
-        .add(";\n");
-    return injectionMethod.build();
-  }
-
-  private static InjectionMethod fieldProxy(
-      ClassName proxyEnclosingClass,
-      VariableElement field,
-      String methodName,
-      DaggerElements elements) {
-    TypeElement enclosingType = MoreElements.asType(field.getEnclosingElement());
-    InjectionMethod.Builder injectionMethod =
-        InjectionMethod.builder(elements).name(methodName).enclosingClass(proxyEnclosingClass);
-    injectionMethod.copyTypeParameters(enclosingType);
-
-    ParameterSpec instance =
-        injectionMethod.addParameter("instance", accessibleType(enclosingType.asType(), elements));
-    CodeBlock parameter = injectionMethod.copyParameter(field);
-    injectionMethod
-        .methodBodyBuilder()
-        .addStatement(
-            "$L.$L = $L",
-            instanceWithPotentialCast(CodeBlock.of("$N", instance), enclosingType.asType()),
-            field.getSimpleName(),
-            parameter);
-    return injectionMethod.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectionOrProvisionProviderCreationExpression.java b/java/dagger/internal/codegen/InjectionOrProvisionProviderCreationExpression.java
deleted file mode 100644
index 2d2e8cb..0000000
--- a/java/dagger/internal/codegen/InjectionOrProvisionProviderCreationExpression.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-import static dagger.model.BindingKind.INJECTION;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import javax.inject.Provider;
-
-/**
- * A {@link Provider} creation expression for an {@link javax.inject.Inject @Inject}-constructed
- * class or a {@link dagger.Provides @Provides}-annotated module method.
- */
-// TODO(dpb): Resolve with ProducerCreationExpression.
-final class InjectionOrProvisionProviderCreationExpression
-    implements FrameworkInstanceCreationExpression {
-
-  private final ContributionBinding binding;
-  private final ComponentBindingExpressions componentBindingExpressions;
-
-  InjectionOrProvisionProviderCreationExpression(
-      ContributionBinding binding, ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    CodeBlock createFactory =
-        CodeBlock.of(
-            "$T.create($L)",
-            generatedClassNameForBinding(binding),
-            componentBindingExpressions.getCreateMethodArgumentsCodeBlock(binding));
-
-    // When scoping a parameterized factory for an @Inject class, Java 7 cannot always infer the
-    // type properly, so cast to a raw framework type before scoping.
-    if (binding.kind().equals(INJECTION)
-        && binding.unresolved().isPresent()
-        && binding.scope().isPresent()) {
-      return CodeBlocks.cast(createFactory, Provider.class);
-    } else {
-      return createFactory;
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectionSiteFactory.java b/java/dagger/internal/codegen/InjectionSiteFactory.java
deleted file mode 100644
index d09f91d..0000000
--- a/java/dagger/internal/codegen/InjectionSiteFactory.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2017 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.auto.common.MoreElements.isAnnotationPresent;
-import static dagger.internal.codegen.MembersInjectionBinding.InjectionSite.Kind.METHOD;
-import static dagger.internal.codegen.langmodel.DaggerElements.DECLARATION_ORDER;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.SetMultimap;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementKindVisitor8;
-
-/** A factory for {@link Binding} objects. */
-final class InjectionSiteFactory {
-  private final ElementVisitor<Optional<InjectionSite>, DeclaredType> injectionSiteVisitor =
-      new ElementKindVisitor8<Optional<InjectionSite>, DeclaredType>(Optional.empty()) {
-        @Override
-        public Optional<InjectionSite> visitExecutableAsMethod(
-            ExecutableElement method, DeclaredType type) {
-          ExecutableType resolved = MoreTypes.asExecutable(types.asMemberOf(type, method));
-          return Optional.of(
-              InjectionSite.method(
-                  method,
-                  dependencyRequestFactory.forRequiredResolvedVariables(
-                      method.getParameters(), resolved.getParameterTypes())));
-        }
-
-        @Override
-        public Optional<InjectionSite> visitVariableAsField(
-            VariableElement field, DeclaredType type) {
-          if (!isAnnotationPresent(field, Inject.class)
-              || field.getModifiers().contains(PRIVATE)
-              || field.getModifiers().contains(STATIC)) {
-            return Optional.empty();
-          }
-          TypeMirror resolved = types.asMemberOf(type, field);
-          return Optional.of(
-              InjectionSite.field(
-                  field, dependencyRequestFactory.forRequiredResolvedVariable(field, resolved)));
-        }
-      };
-
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final DependencyRequestFactory dependencyRequestFactory;
-
-  @Inject
-  InjectionSiteFactory(
-      DaggerTypes types,
-      DaggerElements elements,
-      DependencyRequestFactory dependencyRequestFactory) {
-    this.types = types;
-    this.elements = elements;
-    this.dependencyRequestFactory = dependencyRequestFactory;
-  }
-
-  /** Returns the injection sites for a type. */
-  ImmutableSortedSet<InjectionSite> getInjectionSites(DeclaredType declaredType) {
-    Set<InjectionSite> injectionSites = new HashSet<>();
-    List<TypeElement> ancestors = new ArrayList<>();
-    SetMultimap<String, ExecutableElement> overriddenMethodMap = LinkedHashMultimap.create();
-    for (Optional<DeclaredType> currentType = Optional.of(declaredType);
-        currentType.isPresent();
-        currentType = types.nonObjectSuperclass(currentType.get())) {
-      DeclaredType type = currentType.get();
-      ancestors.add(MoreElements.asType(type.asElement()));
-      for (Element enclosedElement : type.asElement().getEnclosedElements()) {
-        Optional<InjectionSite> maybeInjectionSite =
-            injectionSiteVisitor.visit(enclosedElement, type);
-        if (maybeInjectionSite.isPresent()) {
-          InjectionSite injectionSite = maybeInjectionSite.get();
-          if (shouldBeInjected(injectionSite.element(), overriddenMethodMap)) {
-            injectionSites.add(injectionSite);
-          }
-          if (injectionSite.kind().equals(METHOD)) {
-            ExecutableElement injectionSiteMethod =
-                MoreElements.asExecutable(injectionSite.element());
-            overriddenMethodMap.put(
-                injectionSiteMethod.getSimpleName().toString(), injectionSiteMethod);
-          }
-        }
-      }
-    }
-    return ImmutableSortedSet.copyOf(
-        // supertypes before subtypes
-        Comparator.comparing(
-                (InjectionSite injectionSite) ->
-                    ancestors.indexOf(injectionSite.element().getEnclosingElement()))
-            .reversed()
-            // fields before methods
-            .thenComparing(injectionSite -> injectionSite.element().getKind())
-            // then sort by whichever element comes first in the parent
-            // this isn't necessary, but makes the processor nice and predictable
-            .thenComparing(InjectionSite::element, DECLARATION_ORDER),
-        injectionSites);
-  }
-
-  private boolean shouldBeInjected(
-      Element injectionSite, SetMultimap<String, ExecutableElement> overriddenMethodMap) {
-    if (!isAnnotationPresent(injectionSite, Inject.class)
-        || injectionSite.getModifiers().contains(PRIVATE)
-        || injectionSite.getModifiers().contains(STATIC)) {
-      return false;
-    }
-
-    if (injectionSite.getKind().isField()) { // Inject all fields (self and ancestors)
-      return true;
-    }
-
-    // For each method with the same name belonging to any descendant class, return false if any
-    // method has already overridden the injectionSite method. To decrease the number of methods
-    // that are checked, we store the already injected methods in a SetMultimap and only
-    // check the methods with the same name.
-    ExecutableElement injectionSiteMethod = MoreElements.asExecutable(injectionSite);
-    TypeElement injectionSiteType = MoreElements.asType(injectionSite.getEnclosingElement());
-    for (ExecutableElement method :
-        overriddenMethodMap.get(injectionSiteMethod.getSimpleName().toString())) {
-      if (elements.overrides(method, injectionSiteMethod, injectionSiteType)) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
diff --git a/java/dagger/internal/codegen/InnerSwitchingProviders.java b/java/dagger/internal/codegen/InnerSwitchingProviders.java
deleted file mode 100644
index 74c4366..0000000
--- a/java/dagger/internal/codegen/InnerSwitchingProviders.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2018 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.squareup.javapoet.MethodSpec.constructorBuilder;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.model.RequestKind.INSTANCE;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Generates {@linkplain BindingExpression binding expressions} for a binding that is represented by
- * an inner {@code SwitchingProvider} class.
- */
-final class InnerSwitchingProviders extends SwitchingProviders {
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-
-  InnerSwitchingProviders(
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types) {
-    super(componentImplementation, types);
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.types = types;
-  }
-
-  /**
-   * Returns the binding expression for a binding that satisfies a {@link Provider} requests with a
-   * inner {@code SwitchingProvider} class.
-   */
-  BindingExpression newBindingExpression(ContributionBinding binding) {
-    return new BindingExpression() {
-      @Override
-      Expression getDependencyExpression(ClassName requestingClass) {
-        return getProviderExpression(new SwitchCase(binding, requestingClass));
-      }
-    };
-  }
-
-  @Override
-  protected TypeSpec createSwitchingProviderType(TypeSpec.Builder builder) {
-    return builder
-        .addModifiers(PRIVATE, FINAL)
-        .addField(TypeName.INT, "id", PRIVATE, FINAL)
-        .addMethod(
-            constructorBuilder()
-                .addParameter(TypeName.INT, "id")
-                .addStatement("this.id = id")
-                .build())
-        .build();
-  }
-
-  private final class SwitchCase implements SwitchingProviders.SwitchCase {
-    private final ContributionBinding binding;
-    private final ClassName requestingClass;
-
-    SwitchCase(ContributionBinding binding, ClassName requestingClass) {
-      this.binding = binding;
-      this.requestingClass = requestingClass;
-    }
-
-    @Override
-    public Key key() {
-      return binding.key();
-    }
-
-    @Override
-    public Expression getProviderExpression(ClassName switchingProviderClass, int switchId) {
-      TypeMirror instanceType = types.accessibleType(binding.contributedType(), requestingClass);
-      return Expression.create(
-          types.wrapType(instanceType, Provider.class),
-          CodeBlock.of("new $T<>($L)", switchingProviderClass, switchId));
-    }
-
-    @Override
-    public Expression getReturnExpression(ClassName switchingProviderClass) {
-      return componentBindingExpressions.getDependencyExpression(
-          bindingRequest(binding.key(), INSTANCE), switchingProviderClass);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/InstanceFactoryCreationExpression.java b/java/dagger/internal/codegen/InstanceFactoryCreationExpression.java
deleted file mode 100644
index c9b26d7..0000000
--- a/java/dagger/internal/codegen/InstanceFactoryCreationExpression.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.InstanceFactory;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import java.util.function.Supplier;
-
-/**
- * A {@link FrameworkInstanceCreationExpression} that creates an {@link InstanceFactory} for an
- * instance.
- */
-final class InstanceFactoryCreationExpression implements FrameworkInstanceCreationExpression {
-
-  private final boolean nullable;
-  private final Supplier<CodeBlock> instanceExpression;
-
-  InstanceFactoryCreationExpression(Supplier<CodeBlock> instanceExpression) {
-    this(false, instanceExpression);
-  }
-
-  InstanceFactoryCreationExpression(boolean nullable, Supplier<CodeBlock> instanceExpression) {
-    this.nullable = nullable;
-    this.instanceExpression = checkNotNull(instanceExpression);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    return CodeBlock.of(
-        "$T.$L($L)",
-        InstanceFactory.class,
-        nullable ? "createNullable" : "create",
-        instanceExpression.get());
-  }
-
-  @Override
-  public boolean useInnerSwitchingProvider() {
-    return false;
-  }
-}
diff --git a/java/dagger/internal/codegen/JavacPluginModule.java b/java/dagger/internal/codegen/JavacPluginModule.java
deleted file mode 100644
index bc5b66e..0000000
--- a/java/dagger/internal/codegen/JavacPluginModule.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2017 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 dagger.internal.codegen.ValidationType.NONE;
-import static javax.tools.Diagnostic.Kind.NOTE;
-
-import com.sun.tools.javac.model.JavacElements;
-import com.sun.tools.javac.model.JavacTypes;
-import com.sun.tools.javac.util.Context;
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Types;
-import javax.tools.Diagnostic;
-
-/**
- * A module that provides a {@link BindingGraphFactory} and {@link ComponentDescriptorFactory} for
- * use in {@code javac} plugins. Requires a binding for the {@code javac} {@link Context}.
- */
-@Module(includes = InjectBindingRegistryModule.class)
-abstract class JavacPluginModule {
-  @Provides
-  static CompilerOptions compilerOptions() {
-    return new CompilerOptions() {
-      @Override
-      boolean usesProducers() {
-        return true;
-      }
-
-      @Override
-      boolean fastInit() {
-        return false;
-      }
-
-      @Override
-      boolean formatGeneratedSource() {
-        return false;
-      }
-
-      @Override
-      boolean writeProducerNameInToken() {
-        return true;
-      }
-
-      @Override
-      Diagnostic.Kind nullableValidationKind() {
-        return NOTE;
-      }
-
-      @Override
-      Diagnostic.Kind privateMemberValidationKind() {
-        return NOTE;
-      }
-
-      @Override
-      Diagnostic.Kind staticMemberValidationKind() {
-        return NOTE;
-      }
-
-      @Override
-      boolean ignorePrivateAndStaticInjectionForComponent() {
-        return false;
-      }
-
-      @Override
-      ValidationType scopeCycleValidationType() {
-        return NONE;
-      }
-
-      @Override
-      boolean warnIfInjectionFactoryNotGeneratedUpstream() {
-        return false;
-      }
-
-      @Override
-      boolean headerCompilation() {
-        return false;
-      }
-
-      @Override
-      boolean aheadOfTimeSubcomponents() {
-        return false;
-      }
-
-      @Override
-      boolean forceUseSerializedComponentImplementations() {
-        return false;
-      }
-
-      @Override
-      boolean emitModifiableMetadataAnnotations() {
-        return false;
-      }
-
-      @Override
-      boolean useGradleIncrementalProcessing() {
-        return false;
-      }
-
-      @Override
-      ValidationType fullBindingGraphValidationType(TypeElement element) {
-        return NONE;
-      }
-
-      @Override
-      Diagnostic.Kind moduleHasDifferentScopesDiagnosticKind() {
-        return NOTE;
-      }
-
-      @Override
-      ValidationType explicitBindingConflictsWithInjectValidationType() {
-        return NONE;
-      }
-    };
-  }
-
-  @Binds
-  abstract Messager messager(NullMessager nullMessager);
-
-  static final class NullMessager implements Messager {
-
-    @Inject
-    NullMessager() {}
-
-    @Override
-    public void printMessage(Diagnostic.Kind kind, CharSequence charSequence) {}
-
-    @Override
-    public void printMessage(Diagnostic.Kind kind, CharSequence charSequence, Element element) {}
-
-    @Override
-    public void printMessage(
-        Diagnostic.Kind kind,
-        CharSequence charSequence,
-        Element element,
-        AnnotationMirror annotationMirror) {}
-
-    @Override
-    public void printMessage(
-        Diagnostic.Kind kind,
-        CharSequence charSequence,
-        Element element,
-        AnnotationMirror annotationMirror,
-        AnnotationValue annotationValue) {}
-  }
-
-  @Provides
-  static DaggerElements daggerElements(Context javaContext) {
-    return new DaggerElements(
-        JavacElements.instance(javaContext), JavacTypes.instance(javaContext));
-  }
-
-  @Provides
-  static DaggerTypes daggerTypes(Context javaContext, DaggerElements elements) {
-    return new DaggerTypes(JavacTypes.instance(javaContext), elements);
-  }
-
-  @Binds abstract Types types(DaggerTypes daggerTypes);
-
-  private JavacPluginModule() {}
-}
diff --git a/java/dagger/internal/codegen/KeyFactory.java b/java/dagger/internal/codegen/KeyFactory.java
deleted file mode 100644
index b6ac27f..0000000
--- a/java/dagger/internal/codegen/KeyFactory.java
+++ /dev/null
@@ -1,469 +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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.auto.common.MoreTypes.asExecutable;
-import static com.google.auto.common.MoreTypes.isType;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
-import static dagger.internal.codegen.MapKeys.getMapKey;
-import static dagger.internal.codegen.MapKeys.mapKeyType;
-import static dagger.internal.codegen.Optionals.firstPresent;
-import static dagger.internal.codegen.RequestKinds.extractKeyType;
-import static dagger.internal.codegen.RequestKinds.getRequestKind;
-import static dagger.internal.codegen.langmodel.DaggerTypes.isFutureType;
-import static java.util.Arrays.asList;
-import static javax.lang.model.element.ElementKind.METHOD;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.Binds;
-import dagger.BindsOptionalOf;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.internal.codegen.serialization.KeyProto;
-import dagger.model.Key;
-import dagger.model.Key.MultibindingContributionIdentifier;
-import dagger.model.RequestKind;
-import dagger.multibindings.Multibinds;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.Production;
-import dagger.producers.internal.ProductionImplementation;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-
-/** A factory for {@link Key}s. */
-final class KeyFactory {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final TypeProtoConverter typeProtoConverter;
-  private final AnnotationProtoConverter annotationProtoConverter;
-
-  @Inject
-  KeyFactory(
-      DaggerTypes types,
-      DaggerElements elements,
-      TypeProtoConverter typeProtoConverter,
-      AnnotationProtoConverter annotationProtoConverter) {
-    this.types = checkNotNull(types);
-    this.elements = checkNotNull(elements);
-    this.typeProtoConverter = typeProtoConverter;
-    this.annotationProtoConverter = annotationProtoConverter;
-  }
-
-  private TypeMirror boxPrimitives(TypeMirror type) {
-    return type.getKind().isPrimitive() ? types.boxedClass((PrimitiveType) type).asType() : type;
-  }
-
-  private DeclaredType setOf(TypeMirror elementType) {
-    return types.getDeclaredType(elements.getTypeElement(Set.class), boxPrimitives(elementType));
-  }
-
-  private DeclaredType mapOf(TypeMirror keyType, TypeMirror valueType) {
-    return types.getDeclaredType(
-        elements.getTypeElement(Map.class), boxPrimitives(keyType), boxPrimitives(valueType));
-  }
-
-  /** Returns {@code Map<KeyType, FrameworkType<ValueType>>}. */
-  private TypeMirror mapOfFrameworkType(
-      TypeMirror keyType, TypeElement frameworkType, TypeMirror valueType) {
-    return mapOf(keyType, types.getDeclaredType(frameworkType, boxPrimitives(valueType)));
-  }
-
-  Key forComponentMethod(ExecutableElement componentMethod) {
-    checkArgument(componentMethod.getKind().equals(METHOD));
-    return forMethod(componentMethod, componentMethod.getReturnType());
-  }
-
-  Key forProductionComponentMethod(ExecutableElement componentMethod) {
-    checkArgument(componentMethod.getKind().equals(METHOD));
-    TypeMirror returnType = componentMethod.getReturnType();
-    TypeMirror keyType =
-        isFutureType(returnType)
-            ? getOnlyElement(MoreTypes.asDeclared(returnType).getTypeArguments())
-            : returnType;
-    return forMethod(componentMethod, keyType);
-  }
-
-  Key forSubcomponentCreatorMethod(
-      ExecutableElement subcomponentCreatorMethod, DeclaredType declaredContainer) {
-    checkArgument(subcomponentCreatorMethod.getKind().equals(METHOD));
-    ExecutableType resolvedMethod =
-        asExecutable(types.asMemberOf(declaredContainer, subcomponentCreatorMethod));
-    return Key.builder(resolvedMethod.getReturnType()).build();
-  }
-
-  Key forSubcomponentCreator(TypeMirror creatorType) {
-    return Key.builder(creatorType).build();
-  }
-
-  Key forProvidesMethod(ExecutableElement method, TypeElement contributingModule) {
-    return forBindingMethod(
-        method, contributingModule, Optional.of(elements.getTypeElement(Provider.class)));
-  }
-
-  Key forProducesMethod(ExecutableElement method, TypeElement contributingModule) {
-    return forBindingMethod(
-        method, contributingModule, Optional.of(elements.getTypeElement(Producer.class)));
-  }
-
-  /** Returns the key bound by a {@link Binds} method. */
-  Key forBindsMethod(ExecutableElement method, TypeElement contributingModule) {
-    checkArgument(isAnnotationPresent(method, Binds.class));
-    return forBindingMethod(method, contributingModule, Optional.empty());
-  }
-
-  /** Returns the base key bound by a {@link BindsOptionalOf} method. */
-  Key forBindsOptionalOfMethod(ExecutableElement method, TypeElement contributingModule) {
-    checkArgument(isAnnotationPresent(method, BindsOptionalOf.class));
-    return forBindingMethod(method, contributingModule, Optional.empty());
-  }
-
-  private Key forBindingMethod(
-      ExecutableElement method,
-      TypeElement contributingModule,
-      Optional<TypeElement> frameworkType) {
-    checkArgument(method.getKind().equals(METHOD));
-    ExecutableType methodType =
-        MoreTypes.asExecutable(
-            types.asMemberOf(MoreTypes.asDeclared(contributingModule.asType()), method));
-    ContributionType contributionType = ContributionType.fromBindingElement(method);
-    TypeMirror returnType = methodType.getReturnType();
-    if (frameworkType.isPresent()
-        && frameworkType.get().equals(elements.getTypeElement(Producer.class))
-        && isType(returnType)) {
-      if (isFutureType(methodType.getReturnType())) {
-        returnType = getOnlyElement(MoreTypes.asDeclared(returnType).getTypeArguments());
-      } else if (contributionType.equals(ContributionType.SET_VALUES)
-          && SetType.isSet(returnType)) {
-        SetType setType = SetType.from(returnType);
-        if (isFutureType(setType.elementType())) {
-          returnType =
-              types.getDeclaredType(
-                  elements.getTypeElement(Set.class), types.unwrapType(setType.elementType()));
-        }
-      }
-    }
-    TypeMirror keyType = bindingMethodKeyType(returnType, method, contributionType, frameworkType);
-    Key key = forMethod(method, keyType);
-    return contributionType.equals(ContributionType.UNIQUE)
-        ? key
-        : key.toBuilder()
-            .multibindingContributionIdentifier(
-                new MultibindingContributionIdentifier(method, contributingModule))
-            .build();
-  }
-
-  /**
-   * Returns the key for a {@link Multibinds @Multibinds} method.
-   *
-   * <p>The key's type is either {@code Set<T>} or {@code Map<K, Provider<V>>}. The latter works
-   * even for maps used by {@code Producer}s.
-   */
-  Key forMultibindsMethod(ExecutableType executableType, ExecutableElement method) {
-    checkArgument(method.getKind().equals(METHOD), "%s must be a method", method);
-    TypeMirror returnType = executableType.getReturnType();
-    TypeMirror keyType =
-        MapType.isMap(returnType)
-            ? mapOfFrameworkType(
-                MapType.from(returnType).keyType(),
-                elements.getTypeElement(Provider.class),
-                MapType.from(returnType).valueType())
-            : returnType;
-    return forMethod(method, keyType);
-  }
-
-  private TypeMirror bindingMethodKeyType(
-      TypeMirror returnType,
-      ExecutableElement method,
-      ContributionType contributionType,
-      Optional<TypeElement> frameworkType) {
-    switch (contributionType) {
-      case UNIQUE:
-        return returnType;
-      case SET:
-        return setOf(returnType);
-      case MAP:
-        TypeMirror mapKeyType = mapKeyType(getMapKey(method).get(), types);
-        return frameworkType.isPresent()
-            ? mapOfFrameworkType(mapKeyType, frameworkType.get(), returnType)
-            : mapOf(mapKeyType, returnType);
-      case SET_VALUES:
-        // TODO(gak): do we want to allow people to use "covariant return" here?
-        checkArgument(SetType.isSet(returnType));
-        return returnType;
-    }
-    throw new AssertionError();
-  }
-
-  /**
-   * Returns the key for a binding associated with a {@link DelegateDeclaration}.
-   *
-   * <p>If {@code delegateDeclaration} is {@code @IntoMap}, transforms the {@code Map<K, V>} key
-   * from {@link DelegateDeclaration#key()} to {@code Map<K, FrameworkType<V>>}. If {@code
-   * delegateDeclaration} is not a map contribution, its key is returned.
-   */
-  Key forDelegateBinding(DelegateDeclaration delegateDeclaration, Class<?> frameworkType) {
-    return delegateDeclaration.contributionType().equals(ContributionType.MAP)
-        ? wrapMapValue(delegateDeclaration.key(), frameworkType)
-        : delegateDeclaration.key();
-  }
-
-  private Key forMethod(ExecutableElement method, TypeMirror keyType) {
-    return forQualifiedType(getQualifier(method), keyType);
-  }
-
-  Key forInjectConstructorWithResolvedType(TypeMirror type) {
-    return Key.builder(type).build();
-  }
-
-  // TODO(ronshapiro): Remove these conveniences which are simple wrappers around Key.Builder
-  Key forType(TypeMirror type) {
-    return Key.builder(type).build();
-  }
-
-  Key forMembersInjectedType(TypeMirror type) {
-    return Key.builder(type).build();
-  }
-
-  Key forQualifiedType(Optional<AnnotationMirror> qualifier, TypeMirror type) {
-    return Key.builder(boxPrimitives(type)).qualifier(qualifier).build();
-  }
-
-  Key forProductionExecutor() {
-    return Key.builder(elements.getTypeElement(Executor.class).asType())
-        .qualifier(SimpleAnnotationMirror.of(elements.getTypeElement(Production.class)))
-        .build();
-  }
-
-  Key forProductionImplementationExecutor() {
-    return Key.builder(elements.getTypeElement(Executor.class).asType())
-        .qualifier(SimpleAnnotationMirror.of(elements.getTypeElement(ProductionImplementation.class)))
-        .build();
-  }
-
-  Key forProductionComponentMonitor() {
-    return Key.builder(elements.getTypeElement(ProductionComponentMonitor.class).asType()).build();
-  }
-
-  /**
-   * If {@code requestKey} is for a {@code Map<K, V>} or {@code Map<K, Produced<V>>}, returns keys
-   * for {@code Map<K, Provider<V>>} and {@code Map<K, Producer<V>>} (if Dagger-Producers is on
-   * the classpath).
-   */
-  ImmutableSet<Key> implicitFrameworkMapKeys(Key requestKey) {
-    return Stream.of(implicitMapProviderKeyFrom(requestKey), implicitMapProducerKeyFrom(requestKey))
-        .filter(Optional::isPresent)
-        .map(Optional::get)
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Optionally extract a {@link Key} for the underlying provision binding(s) if such a valid key
-   * can be inferred from the given key. Specifically, if the key represents a {@link Map}{@code
-   * <K, V>} or {@code Map<K, Producer<V>>}, a key of {@code Map<K, Provider<V>>} will be
-   * returned.
-   */
-  Optional<Key> implicitMapProviderKeyFrom(Key possibleMapKey) {
-    return firstPresent(
-        rewrapMapKey(possibleMapKey, Produced.class, Provider.class),
-        wrapMapKey(possibleMapKey, Provider.class));
-  }
-
-  /**
-   * Optionally extract a {@link Key} for the underlying production binding(s) if such a
-   * valid key can be inferred from the given key.  Specifically, if the key represents a
-   * {@link Map}{@code <K, V>} or {@code Map<K, Produced<V>>}, a key of
-   * {@code Map<K, Producer<V>>} will be returned.
-   */
-  Optional<Key> implicitMapProducerKeyFrom(Key possibleMapKey) {
-    return firstPresent(
-        rewrapMapKey(possibleMapKey, Produced.class, Producer.class),
-        wrapMapKey(possibleMapKey, Producer.class));
-  }
-
-  /**
-   * If {@code key}'s type is {@code Map<K, Provider<V>>}, {@code Map<K, Producer<V>>}, or {@code
-   * Map<K, Produced<V>>}, returns a key with the same qualifier and {@link
-   * Key#multibindingContributionIdentifier()} whose type is simply {@code Map<K, V>}.
-   *
-   * <p>Otherwise, returns {@code key}.
-   */
-  Key unwrapMapValueType(Key key) {
-    if (MapType.isMap(key)) {
-      MapType mapType = MapType.from(key);
-      if (!mapType.isRawType()) {
-        for (Class<?> frameworkClass : asList(Provider.class, Producer.class, Produced.class)) {
-          if (mapType.valuesAreTypeOf(frameworkClass)) {
-            return key.toBuilder()
-                .type(mapOf(mapType.keyType(), mapType.unwrappedValueType(frameworkClass)))
-                .build();
-          }
-        }
-      }
-    }
-    return key;
-  }
-
-  /**
-   * Converts a {@link Key} of type {@code Map<K, V>} to {@code Map<K, Provider<V>>}.
-   */
-  private Key wrapMapValue(Key key, Class<?> newWrappingClass) {
-    checkArgument(
-        FrameworkTypes.isFrameworkType(elements.getTypeElement(newWrappingClass).asType()));
-    return wrapMapKey(key, newWrappingClass).get();
-  }
-
-  /**
-   * If {@code key}'s type is {@code Map<K, CurrentWrappingClass<Bar>>}, returns a key with type
-   * {@code Map<K, NewWrappingClass<Bar>>} with the same qualifier. Otherwise returns {@link
-   * Optional#empty()}.
-   *
-   * <p>Returns {@link Optional#empty()} if {@code newWrappingClass} is not in the classpath.
-   *
-   * @throws IllegalArgumentException if {@code newWrappingClass} is the same as {@code
-   *     currentWrappingClass}
-   */
-  Optional<Key> rewrapMapKey(
-      Key possibleMapKey, Class<?> currentWrappingClass, Class<?> newWrappingClass) {
-    checkArgument(!currentWrappingClass.equals(newWrappingClass));
-    if (MapType.isMap(possibleMapKey)) {
-      MapType mapType = MapType.from(possibleMapKey);
-      if (!mapType.isRawType() && mapType.valuesAreTypeOf(currentWrappingClass)) {
-        TypeElement wrappingElement = elements.getTypeElement(newWrappingClass);
-        if (wrappingElement == null) {
-          // This target might not be compiled with Producers, so wrappingClass might not have an
-          // associated element.
-          return Optional.empty();
-        }
-        DeclaredType wrappedValueType =
-            types.getDeclaredType(
-                wrappingElement, mapType.unwrappedValueType(currentWrappingClass));
-        return Optional.of(
-            possibleMapKey.toBuilder().type(mapOf(mapType.keyType(), wrappedValueType)).build());
-      }
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * If {@code key}'s type is {@code Map<K, Foo>} and {@code Foo} is not {@code WrappingClass
-   * <Bar>}, returns a key with type {@code Map<K, WrappingClass<Foo>>} with the same qualifier.
-   * Otherwise returns {@link Optional#empty()}.
-   *
-   * <p>Returns {@link Optional#empty()} if {@code WrappingClass} is not in the classpath.
-   */
-  private Optional<Key> wrapMapKey(Key possibleMapKey, Class<?> wrappingClass) {
-    if (MapType.isMap(possibleMapKey)) {
-      MapType mapType = MapType.from(possibleMapKey);
-      if (!mapType.isRawType() && !mapType.valuesAreTypeOf(wrappingClass)) {
-        TypeElement wrappingElement = elements.getTypeElement(wrappingClass);
-        if (wrappingElement == null) {
-          // This target might not be compiled with Producers, so wrappingClass might not have an
-          // associated element.
-          return Optional.empty();
-        }
-        DeclaredType wrappedValueType = types.getDeclaredType(wrappingElement, mapType.valueType());
-        return Optional.of(
-            possibleMapKey.toBuilder().type(mapOf(mapType.keyType(), wrappedValueType)).build());
-      }
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * If {@code key}'s type is {@code Set<WrappingClass<Bar>>}, returns a key with type {@code Set
-   * <Bar>} with the same qualifier. Otherwise returns {@link Optional#empty()}.
-   */
-  Optional<Key> unwrapSetKey(Key key, Class<?> wrappingClass) {
-    if (SetType.isSet(key)) {
-      SetType setType = SetType.from(key);
-      if (!setType.isRawType() && setType.elementsAreTypeOf(wrappingClass)) {
-        return Optional.of(
-            key.toBuilder().type(setOf(setType.unwrappedElementType(wrappingClass))).build());
-      }
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * If {@code key}'s type is {@code Optional<T>} for some {@code T}, returns a key with the same
-   * qualifier whose type is {@linkplain RequestKinds#extractKeyType(RequestKind, TypeMirror)}
-   * extracted} from {@code T}.
-   */
-  Optional<Key> unwrapOptional(Key key) {
-    if (!OptionalType.isOptional(key)) {
-      return Optional.empty();
-    }
-
-    TypeMirror optionalValueType = OptionalType.from(key).valueType();
-    return Optional.of(
-        key.toBuilder()
-            .type(extractKeyType(getRequestKind(optionalValueType), optionalValueType))
-            .build());
-  }
-
-  /** Translates a {@link Key} to a proto representation. */
-  static KeyProto toProto(Key key) {
-    KeyProto.Builder builder =
-        KeyProto.newBuilder().setType(TypeProtoConverter.toProto(key.type()));
-    key.qualifier().map(AnnotationProtoConverter::toProto).ifPresent(builder::setQualifier);
-    key.multibindingContributionIdentifier()
-        .ifPresent(
-            mci ->
-                builder
-                    .getMultibindingContributionIdentifierBuilder()
-                    .setModule(mci.module())
-                    .setBindingElement(mci.bindingElement()));
-    return builder.build();
-  }
-
-  /** Creates a {@link Key} from its proto representation. */
-  Key fromProto(KeyProto key) {
-    Key.Builder builder = Key.builder(typeProtoConverter.fromProto(key.getType()));
-    if (key.hasQualifier()) {
-      builder.qualifier(annotationProtoConverter.fromProto(key.getQualifier()));
-    }
-    if (key.hasMultibindingContributionIdentifier()) {
-      KeyProto.MultibindingContributionIdentifier multibindingContributionIdentifier =
-          key.getMultibindingContributionIdentifier();
-      builder.multibindingContributionIdentifier(
-          new MultibindingContributionIdentifier(
-              multibindingContributionIdentifier.getBindingElement(),
-              multibindingContributionIdentifier.getModule()));
-    }
-    return builder.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/KeyVariableNamer.java b/java/dagger/internal/codegen/KeyVariableNamer.java
deleted file mode 100644
index 407f208..0000000
--- a/java/dagger/internal/codegen/KeyVariableNamer.java
+++ /dev/null
@@ -1,107 +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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static dagger.internal.codegen.SourceFiles.protectAgainstKeywords;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import java.util.Iterator;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * Suggests a variable name for a type based on a {@link Key}. Prefer {@link
- * DependencyVariableNamer} for cases where a specific {@link DependencyRequest} is present.
- */
-final class KeyVariableNamer {
-  /** Simple names that are very common. Inspired by https://errorprone.info/bugpattern/BadImport */
-  private static final ImmutableSet<String> VERY_SIMPLE_NAMES =
-      ImmutableSet.of(
-          "Builder",
-          "Factory",
-          "Component",
-          "Subcomponent",
-          "Injector");
-
-  private static final TypeVisitor<Void, StringBuilder> TYPE_NAMER =
-      new SimpleTypeVisitor8<Void, StringBuilder>() {
-        @Override
-        public Void visitDeclared(DeclaredType declaredType, StringBuilder builder) {
-          TypeElement element = MoreTypes.asTypeElement(declaredType);
-          if (element.getNestingKind().isNested()
-              && VERY_SIMPLE_NAMES.contains(element.getSimpleName().toString())) {
-            builder.append(element.getEnclosingElement().getSimpleName());
-          }
-
-          builder.append(element.getSimpleName());
-          Iterator<? extends TypeMirror> argumentIterator =
-              declaredType.getTypeArguments().iterator();
-          if (argumentIterator.hasNext()) {
-            builder.append("Of");
-            TypeMirror first = argumentIterator.next();
-            first.accept(this, builder);
-            while (argumentIterator.hasNext()) {
-              builder.append("And");
-              argumentIterator.next().accept(this, builder);
-            }
-          }
-          return null;
-        }
-
-        @Override
-        public Void visitPrimitive(PrimitiveType type, StringBuilder builder) {
-          builder.append(LOWER_CAMEL.to(UPPER_CAMEL, type.toString()));
-          return null;
-        }
-
-        @Override
-        public Void visitArray(ArrayType type, StringBuilder builder) {
-          type.getComponentType().accept(this, builder);
-          builder.append("Array");
-          return null;
-        }
-      };
-
-  private KeyVariableNamer() {}
-
-  static String name(Key key) {
-    if (key.multibindingContributionIdentifier().isPresent()) {
-      return key.multibindingContributionIdentifier().get().bindingElement();
-    }
-
-    StringBuilder builder = new StringBuilder();
-
-    if (key.qualifier().isPresent()) {
-      // TODO(gak): Use a better name for fields with qualifiers with members.
-      builder.append(key.qualifier().get().getAnnotationType().asElement().getSimpleName());
-    }
-
-    key.type().accept(TYPE_NAMER, builder);
-
-    return protectAgainstKeywords(UPPER_CAMEL.to(LOWER_CAMEL, builder.toString()));
-  }
-}
diff --git a/java/dagger/internal/codegen/Keys.java b/java/dagger/internal/codegen/Keys.java
deleted file mode 100644
index 670fda7..0000000
--- a/java/dagger/internal/codegen/Keys.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleTypeVisitor6;
-
-/** Utility methods related to {@link Key}s. */
-final class Keys {
-  static boolean isValidMembersInjectionKey(Key key) {
-    return !key.qualifier().isPresent()
-        && !key.multibindingContributionIdentifier().isPresent()
-        && key.type().getKind().equals(TypeKind.DECLARED);
-  }
-
-  /**
-   * Returns {@code true} if this is valid as an implicit key (that is, if it's valid for a
-   * just-in-time binding by discovering an {@code @Inject} constructor).
-   */
-  static boolean isValidImplicitProvisionKey(Key key, DaggerTypes types) {
-    return isValidImplicitProvisionKey(key.qualifier(), key.type(), types);
-  }
-
-  /**
-   * Returns {@code true} if a key with {@code qualifier} and {@code type} is valid as an implicit
-   * key (that is, if it's valid for a just-in-time binding by discovering an {@code @Inject}
-   * constructor).
-   */
-  static boolean isValidImplicitProvisionKey(
-      Optional<? extends AnnotationMirror> qualifier, TypeMirror type, final DaggerTypes types) {
-    // Qualifiers disqualify implicit provisioning.
-    if (qualifier.isPresent()) {
-      return false;
-    }
-
-    return type.accept(
-        new SimpleTypeVisitor6<Boolean, Void>(false) {
-          @Override
-          public Boolean visitDeclared(DeclaredType type, Void ignored) {
-            // Non-classes or abstract classes aren't allowed.
-            TypeElement element = MoreElements.asType(type.asElement());
-            if (!element.getKind().equals(ElementKind.CLASS)
-                || element.getModifiers().contains(Modifier.ABSTRACT)) {
-              return false;
-            }
-
-            // If the key has type arguments, validate that each type argument is declared.
-            // Otherwise the type argument may be a wildcard (or other type), and we can't
-            // resolve that to actual types.
-            for (TypeMirror arg : type.getTypeArguments()) {
-              if (arg.getKind() != TypeKind.DECLARED) {
-                return false;
-              }
-            }
-
-            // Also validate that the key is not the erasure of a generic type.
-            // If it is, that means the user referred to Foo<T> as just 'Foo',
-            // which we don't allow.  (This is a judgement call -- we *could*
-            // allow it and instantiate the type bounds... but we don't.)
-            return MoreTypes.asDeclared(element.asType()).getTypeArguments().isEmpty()
-                || !types.isSameType(types.erasure(element.asType()), type);
-          }
-        },
-        null);
-  }
-}
diff --git a/java/dagger/internal/codegen/MapBindingExpression.java b/java/dagger/internal/codegen/MapBindingExpression.java
deleted file mode 100644
index 526c493..0000000
--- a/java/dagger/internal/codegen/MapBindingExpression.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.MapKeys.getMapKeyExpression;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static dagger.model.BindingKind.MULTIBOUND_MAP;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.MapBuilder;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import java.util.Collections;
-import java.util.Optional;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** A {@link BindingExpression} for multibound maps. */
-final class MapBindingExpression extends MultibindingExpression {
-  /** Maximum number of key-value pairs that can be passed to ImmutableMap.of(K, V, K, V, ...). */
-  private static final int MAX_IMMUTABLE_MAP_OF_KEY_VALUE_PAIRS = 5;
-
-  private final ProvisionBinding binding;
-  private final ImmutableMap<DependencyRequest, ContributionBinding> dependencies;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  MapBindingExpression(
-      ResolvedBindings resolvedBindings,
-      ComponentImplementation componentImplementation,
-      BindingGraph graph,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      DaggerElements elements) {
-    super(resolvedBindings, componentImplementation);
-    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
-    BindingKind bindingKind = this.binding.kind();
-    checkArgument(bindingKind.equals(MULTIBOUND_MAP), bindingKind);
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.types = types;
-    this.elements = elements;
-    this.dependencies =
-        Maps.toMap(
-            binding.dependencies(),
-            dep -> graph.contributionBindings().get(dep.key()).contributionBinding());
-  }
-
-  @Override
-  protected Expression buildDependencyExpression(ClassName requestingClass) {
-    Optional<CodeBlock> superMethodCall = superMethodCall();
-    // TODO(ronshapiro): We should also make an ImmutableMap version of MapFactory
-    boolean isImmutableMapAvailable = isImmutableMapAvailable();
-    // TODO(ronshapiro, gak): Use Maps.immutableEnumMap() if it's available?
-    if (isImmutableMapAvailable
-        && dependencies.size() <= MAX_IMMUTABLE_MAP_OF_KEY_VALUE_PAIRS
-        && !superMethodCall.isPresent()) {
-      return Expression.create(
-          immutableMapType(),
-          CodeBlock.builder()
-              .add("$T.", ImmutableMap.class)
-              .add(maybeTypeParameters(requestingClass))
-              .add(
-                  "of($L)",
-                  dependencies
-                      .keySet()
-                      .stream()
-                      .map(dependency -> keyAndValueExpression(dependency, requestingClass))
-                      .collect(toParametersCodeBlock()))
-              .build());
-    }
-    switch (dependencies.size()) {
-      case 0:
-        return collectionsStaticFactoryInvocation(requestingClass, CodeBlock.of("emptyMap()"));
-      case 1:
-        return collectionsStaticFactoryInvocation(
-            requestingClass,
-            CodeBlock.of(
-                "singletonMap($L)",
-                keyAndValueExpression(getOnlyElement(dependencies.keySet()), requestingClass)));
-      default:
-        CodeBlock.Builder instantiation = CodeBlock.builder();
-        instantiation
-            .add("$T.", isImmutableMapAvailable ? ImmutableMap.class : MapBuilder.class)
-            .add(maybeTypeParameters(requestingClass));
-        if (isImmutableMapBuilderWithExpectedSizeAvailable()) {
-          instantiation.add("builderWithExpectedSize($L)", dependencies.size());
-        } else if (isImmutableMapAvailable) {
-          instantiation.add("builder()");
-        } else {
-          instantiation.add("newMapBuilder($L)", dependencies.size());
-        }
-        for (DependencyRequest dependency : getNewContributions(dependencies.keySet())) {
-          instantiation.add(".put($L)", keyAndValueExpression(dependency, requestingClass));
-        }
-        if (superMethodCall.isPresent()) {
-          instantiation.add(CodeBlock.of(".putAll($L)", superMethodCall.get()));
-        }
-        return Expression.create(
-            isImmutableMapAvailable ? immutableMapType() : binding.key().type(),
-            instantiation.add(".build()").build());
-    }
-  }
-
-  private DeclaredType immutableMapType() {
-    MapType mapType = MapType.from(binding.key());
-    return types.getDeclaredType(
-        elements.getTypeElement(ImmutableMap.class), mapType.keyType(), mapType.valueType());
-  }
-
-  private CodeBlock keyAndValueExpression(DependencyRequest dependency, ClassName requestingClass) {
-    return CodeBlock.of(
-        "$L, $L",
-        getMapKeyExpression(dependencies.get(dependency), requestingClass, elements),
-        componentBindingExpressions
-            .getDependencyExpression(bindingRequest(dependency), requestingClass)
-            .codeBlock());
-  }
-
-  private Expression collectionsStaticFactoryInvocation(
-      ClassName requestingClass, CodeBlock methodInvocation) {
-    return Expression.create(
-        binding.key().type(),
-        CodeBlock.builder()
-            .add("$T.", Collections.class)
-            .add(maybeTypeParameters(requestingClass))
-            .add(methodInvocation)
-            .build());
-  }
-
-  private CodeBlock maybeTypeParameters(ClassName requestingClass) {
-    TypeMirror bindingKeyType = binding.key().type();
-    MapType mapType = MapType.from(binding.key());
-    return isTypeAccessibleFrom(bindingKeyType, requestingClass.packageName())
-        ? CodeBlock.of("<$T, $T>", mapType.keyType(), mapType.valueType())
-        : CodeBlock.of("");
-  }
-
-  private boolean isImmutableMapBuilderWithExpectedSizeAvailable() {
-    if (isImmutableMapAvailable()) {
-      return methodsIn(elements.getTypeElement(ImmutableMap.class).getEnclosedElements())
-          .stream()
-          .anyMatch(method -> method.getSimpleName().contentEquals("builderWithExpectedSize"));
-    }
-    return false;
-  }
-
-  private boolean isImmutableMapAvailable() {
-    return elements.getTypeElement(ImmutableMap.class) != null;
-  }
-}
diff --git a/java/dagger/internal/codegen/MapFactoryCreationExpression.java b/java/dagger/internal/codegen/MapFactoryCreationExpression.java
deleted file mode 100644
index 187b792..0000000
--- a/java/dagger/internal/codegen/MapFactoryCreationExpression.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.MapKeys.getMapKeyExpression;
-import static dagger.internal.codegen.SourceFiles.mapFactoryClassName;
-
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.DependencyRequest;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/** A factory creation expression for a multibound map. */
-final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpression {
-
-  private final ComponentImplementation componentImplementation;
-  private final BindingGraph graph;
-  private final ContributionBinding binding;
-  private final DaggerElements elements;
-
-  MapFactoryCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions,
-      BindingGraph graph,
-      DaggerElements elements) {
-    super(binding, componentImplementation, componentBindingExpressions);
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.graph = checkNotNull(graph);
-    this.elements = checkNotNull(elements);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    CodeBlock.Builder builder = CodeBlock.builder().add("$T.", mapFactoryClassName(binding));
-    if (!useRawType()) {
-      MapType mapType = MapType.from(binding.key().type());
-      // TODO(ronshapiro): either inline this into mapFactoryClassName, or add a
-      // mapType.unwrappedValueType() method that doesn't require a framework type
-      TypeMirror valueType = mapType.valueType();
-      for (Class<?> frameworkClass :
-          ImmutableSet.of(Provider.class, Producer.class, Produced.class)) {
-        if (mapType.valuesAreTypeOf(frameworkClass)) {
-          valueType = mapType.unwrappedValueType(frameworkClass);
-          break;
-        }
-      }
-      builder.add("<$T, $T>", mapType.keyType(), valueType);
-    }
-
-    builder.add("builder($L)", binding.dependencies().size());
-
-    superContributions()
-        .ifPresent(superContributions -> builder.add(".putAll($L)", superContributions));
-
-    for (DependencyRequest dependency : dependenciesToImplement()) {
-      ContributionBinding contributionBinding =
-          graph.contributionBindings().get(dependency.key()).contributionBinding();
-      builder.add(
-          ".put($L, $L)",
-          getMapKeyExpression(contributionBinding, componentImplementation.name(), elements),
-          multibindingDependencyExpression(dependency));
-    }
-    builder.add(".build()");
-
-    componentImplementation.registerImplementedMultibinding(binding, bindingRequest());
-
-    return builder.build();
-  }
-}
diff --git a/java/dagger/internal/codegen/MapKeyAccessibility.java b/java/dagger/internal/codegen/MapKeyAccessibility.java
deleted file mode 100644
index ce27877..0000000
--- a/java/dagger/internal/codegen/MapKeyAccessibility.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 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 dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-
-import dagger.internal.codegen.langmodel.Accessibility;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Predicate;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-
-final class MapKeyAccessibility extends SimpleAnnotationValueVisitor8<Boolean, Void> {
-  private final Predicate<TypeMirror> accessibilityChecker;
-
-  private MapKeyAccessibility(Predicate<TypeMirror> accessibilityChecker) {
-    this.accessibilityChecker = accessibilityChecker;
-  }
-
-  @Override
-  public Boolean visitAnnotation(AnnotationMirror annotation, Void aVoid) {
-    // The annotation type is not checked, as the generated code will refer to the @AutoAnnotation
-    // generated type which is always public
-    return visitValues(annotation.getElementValues().values());
-  }
-
-  @Override
-  public Boolean visitArray(List<? extends AnnotationValue> values, Void aVoid) {
-    return visitValues(values);
-  }
-
-  private boolean visitValues(Collection<? extends AnnotationValue> values) {
-    return values.stream().allMatch(value -> value.accept(this, null));
-  }
-
-  @Override
-  public Boolean visitEnumConstant(VariableElement enumConstant, Void aVoid) {
-    return accessibilityChecker.test(enumConstant.getEnclosingElement().asType());
-  }
-
-  @Override
-  public Boolean visitType(TypeMirror type, Void aVoid) {
-    return accessibilityChecker.test(type);
-  }
-
-  @Override
-  protected Boolean defaultAction(Object o, Void aVoid) {
-    return true;
-  }
-
-  static boolean isMapKeyAccessibleFrom(AnnotationMirror annotation, String accessingPackage) {
-    return new MapKeyAccessibility(type -> isTypeAccessibleFrom(type, accessingPackage))
-        .visitAnnotation(annotation, null);
-  }
-
-  static boolean isMapKeyPubliclyAccessible(AnnotationMirror annotation) {
-    return new MapKeyAccessibility(Accessibility::isTypePubliclyAccessible)
-        .visitAnnotation(annotation, null);
-  }
-}
diff --git a/java/dagger/internal/codegen/MapKeyProcessingStep.java b/java/dagger/internal/codegen/MapKeyProcessingStep.java
deleted file mode 100644
index 19975a7..0000000
--- a/java/dagger/internal/codegen/MapKeyProcessingStep.java
+++ /dev/null
@@ -1,88 +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 dagger.internal.codegen.MapKeys.getUnwrappedMapKeyType;
-import static javax.lang.model.element.ElementKind.ANNOTATION_TYPE;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.MapKey;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-
-/**
- * The annotation processor responsible for validating the mapKey annotation and auto-generate
- * implementation of annotations marked with {@link MapKey @MapKey} where necessary.
- */
-public class MapKeyProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
-  private final Messager messager;
-  private final DaggerTypes types;
-  private final MapKeyValidator mapKeyValidator;
-  private final AnnotationCreatorGenerator annotationCreatorGenerator;
-  private final UnwrappedMapKeyGenerator unwrappedMapKeyGenerator;
-
-  @Inject
-  MapKeyProcessingStep(
-      Messager messager,
-      DaggerTypes types,
-      MapKeyValidator mapKeyValidator,
-      AnnotationCreatorGenerator annotationCreatorGenerator,
-      UnwrappedMapKeyGenerator unwrappedMapKeyGenerator) {
-    super(MoreElements::asType);
-    this.messager = messager;
-    this.types = types;
-    this.mapKeyValidator = mapKeyValidator;
-    this.annotationCreatorGenerator = annotationCreatorGenerator;
-    this.unwrappedMapKeyGenerator = unwrappedMapKeyGenerator;
-  }
-
-  @Override
-  public Set<Class<? extends Annotation>> annotations() {
-    return ImmutableSet.<Class<? extends Annotation>>of(MapKey.class);
-  }
-
-  @Override
-  protected void process(
-      TypeElement mapKeyAnnotationType, ImmutableSet<Class<? extends Annotation>> annotations) {
-    ValidationReport<Element> mapKeyReport = mapKeyValidator.validate(mapKeyAnnotationType);
-    mapKeyReport.printMessagesTo(messager);
-
-    if (mapKeyReport.isClean()) {
-      MapKey mapkey = mapKeyAnnotationType.getAnnotation(MapKey.class);
-      if (!mapkey.unwrapValue()) {
-        annotationCreatorGenerator.generate(mapKeyAnnotationType, messager);
-      } else if (unwrappedValueKind(mapKeyAnnotationType).equals(ANNOTATION_TYPE)) {
-        unwrappedMapKeyGenerator.generate(mapKeyAnnotationType, messager);
-      }
-    }
-  }
-
-  private ElementKind unwrappedValueKind(TypeElement mapKeyAnnotationType) {
-    DeclaredType unwrappedMapKeyType =
-        getUnwrappedMapKeyType(MoreTypes.asDeclared(mapKeyAnnotationType.asType()), types);
-    return unwrappedMapKeyType.asElement().getKind();
-  }
-}
diff --git a/java/dagger/internal/codegen/MapKeyValidator.java b/java/dagger/internal/codegen/MapKeyValidator.java
deleted file mode 100644
index f2568ef..0000000
--- a/java/dagger/internal/codegen/MapKeyValidator.java
+++ /dev/null
@@ -1,65 +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 javax.lang.model.util.ElementFilter.methodsIn;
-
-import dagger.MapKey;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.List;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeKind;
-
-/**
- * A validator for {@link MapKey} annotations.
- */
-// TODO(dpb,gak): Should unwrapped MapKeys be required to have their single member be named "value"?
-final class MapKeyValidator {
-  private final DaggerElements elements;
-
-  @Inject
-  MapKeyValidator(DaggerElements elements) {
-    this.elements = elements;
-  }
-
-  ValidationReport<Element> validate(Element element) {
-    ValidationReport.Builder<Element> builder = ValidationReport.about(element);
-    List<ExecutableElement> members = methodsIn(((TypeElement) element).getEnclosedElements());
-    if (members.isEmpty()) {
-      builder.addError("Map key annotations must have members", element);
-    } else if (element.getAnnotation(MapKey.class).unwrapValue()) {
-      if (members.size() > 1) {
-        builder.addError(
-            "Map key annotations with unwrapped values must have exactly one member", element);
-      } else if (members.get(0).getReturnType().getKind() == TypeKind.ARRAY) {
-        builder.addError("Map key annotations with unwrapped values cannot use arrays", element);
-      }
-    } else if (autoAnnotationIsMissing()) {
-      builder.addError(
-          "@AutoAnnotation is a necessary dependency if @MapKey(unwrapValue = false). Add a "
-              + "dependency on com.google.auto.value:auto-value:<current version>");
-    }
-    return builder.build();
-  }
-
-  private boolean autoAnnotationIsMissing() {
-    return elements.getTypeElement("com.google.auto.value.AutoAnnotation") == null;
-  }
-}
diff --git a/java/dagger/internal/codegen/MapKeys.java b/java/dagger/internal/codegen/MapKeys.java
deleted file mode 100644
index d8da6af..0000000
--- a/java/dagger/internal/codegen/MapKeys.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
-import static com.google.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.MapKeyAccessibility.isMapKeyPubliclyAccessible;
-import static dagger.internal.codegen.SourceFiles.elementBasedClassName;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.MapKey;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.NoSuchElementException;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-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.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleTypeVisitor6;
-
-/**
- * Methods for extracting {@link MapKey} annotations and key code blocks from binding elements.
- */
-final class MapKeys {
-
-  /**
-   * If {@code bindingElement} is annotated with a {@link MapKey} annotation, returns it.
-   *
-   * @throws IllegalArgumentException if the element is annotated with more than one {@code MapKey}
-   *     annotation
-   */
-  static Optional<AnnotationMirror> getMapKey(Element bindingElement) {
-    ImmutableSet<? extends AnnotationMirror> mapKeys = getMapKeys(bindingElement);
-    return mapKeys.isEmpty()
-        ? Optional.empty()
-        : Optional.<AnnotationMirror>of(getOnlyElement(mapKeys));
-  }
-
-  /**
-   * Returns all of the {@link MapKey} annotations that annotate {@code bindingElement}.
-   */
-  static ImmutableSet<? extends AnnotationMirror> getMapKeys(Element bindingElement) {
-    return getAnnotatedAnnotations(bindingElement, MapKey.class);
-  }
-
-  /**
-   * Returns the annotation value if {@code mapKey}'s type is annotated with
-   * {@link MapKey @MapKey(unwrapValue = true)}.
-   *
-   * @throws IllegalArgumentException if {@code mapKey}'s type is not annotated with
-   *     {@link MapKey @MapKey} at all.
-   */
-  static Optional<? extends AnnotationValue> unwrapValue(AnnotationMirror mapKey) {
-    MapKey mapKeyAnnotation = mapKey.getAnnotationType().asElement().getAnnotation(MapKey.class);
-    checkArgument(
-        mapKeyAnnotation != null, "%s is not annotated with @MapKey", mapKey.getAnnotationType());
-    return mapKeyAnnotation.unwrapValue()
-        ? Optional.of(getOnlyElement(getAnnotationValuesWithDefaults(mapKey).values()))
-        : Optional.empty();
-  }
-
-  static TypeMirror mapKeyType(AnnotationMirror mapKeyAnnotation, DaggerTypes types) {
-    return unwrapValue(mapKeyAnnotation).isPresent()
-        ? getUnwrappedMapKeyType(mapKeyAnnotation.getAnnotationType(), types)
-        : mapKeyAnnotation.getAnnotationType();
-  }
-
-  /**
-   * Returns the map key type for an unwrapped {@link MapKey} annotation type. If the single member
-   * type is primitive, returns the boxed type.
-   *
-   * @throws IllegalArgumentException if {@code mapKeyAnnotationType} is not an annotation type or
-   *     has more than one member, or if its single member is an array
-   * @throws NoSuchElementException if the annotation has no members
-   */
-  static DeclaredType getUnwrappedMapKeyType(
-      final DeclaredType mapKeyAnnotationType, final DaggerTypes types) {
-    checkArgument(
-        MoreTypes.asTypeElement(mapKeyAnnotationType).getKind() == ElementKind.ANNOTATION_TYPE,
-        "%s is not an annotation type",
-        mapKeyAnnotationType);
-
-    final ExecutableElement onlyElement =
-        getOnlyElement(methodsIn(mapKeyAnnotationType.asElement().getEnclosedElements()));
-
-    SimpleTypeVisitor6<DeclaredType, Void> keyTypeElementVisitor =
-        new SimpleTypeVisitor6<DeclaredType, Void>() {
-
-          @Override
-          public DeclaredType visitArray(ArrayType t, Void p) {
-            throw new IllegalArgumentException(
-                mapKeyAnnotationType + "." + onlyElement.getSimpleName() + " cannot be an array");
-          }
-
-          @Override
-          public DeclaredType visitPrimitive(PrimitiveType t, Void p) {
-            return MoreTypes.asDeclared(types.boxedClass(t).asType());
-          }
-
-          @Override
-          public DeclaredType visitDeclared(DeclaredType t, Void p) {
-            return t;
-          }
-        };
-    return keyTypeElementVisitor.visit(onlyElement.getReturnType());
-  }
-
-  /**
-   * Returns a code block for {@code binding}'s {@link ContributionBinding#mapKeyAnnotation() map
-   * key}. If for whatever reason the map key is not accessible from within {@code requestingClass}
-   * (i.e. it has a package-private {@code enum} from a different package), this will return an
-   * invocation of a proxy-method giving it access.
-   *
-   * @throws IllegalStateException if {@code binding} is not a {@link dagger.multibindings.IntoMap
-   *     map} contribution.
-   */
-  static CodeBlock getMapKeyExpression(
-      ContributionBinding binding, ClassName requestingClass, DaggerElements elements) {
-    AnnotationMirror mapKeyAnnotation = binding.mapKeyAnnotation().get();
-    return MapKeyAccessibility.isMapKeyAccessibleFrom(
-            mapKeyAnnotation, requestingClass.packageName())
-        ? directMapKeyExpression(mapKeyAnnotation, elements)
-        : CodeBlock.of("$T.create()", mapKeyProxyClassName(binding));
-  }
-
-  /**
-   * Returns a code block for the map key annotation {@code mapKey}.
-   *
-   * <p>This method assumes the map key will be accessible in the context that the returned {@link
-   * CodeBlock} is used. Use {@link #getMapKeyExpression(ContributionBinding, ClassName,
-   * DaggerElements)} when that assumption is not guaranteed.
-   *
-   * @throws IllegalArgumentException if the element is annotated with more than one {@code MapKey}
-   *     annotation
-   * @throws IllegalStateException if {@code bindingElement} is not annotated with a {@code MapKey}
-   *     annotation
-   */
-  private static CodeBlock directMapKeyExpression(
-      AnnotationMirror mapKey, DaggerElements elements) {
-    Optional<? extends AnnotationValue> unwrappedValue = unwrapValue(mapKey);
-    AnnotationExpression annotationExpression = new AnnotationExpression(mapKey);
-
-    if (MoreTypes.asTypeElement(mapKey.getAnnotationType())
-        .getQualifiedName()
-        .contentEquals("dagger.android.AndroidInjectionKey")) {
-      TypeElement unwrappedType =
-          elements.checkTypePresent((String) unwrappedValue.get().getValue());
-      return CodeBlock.of(
-          "$T.of($S)",
-          ClassName.get("dagger.android.internal", "AndroidInjectionKeys"),
-          ClassName.get(unwrappedType).reflectionName());
-    }
-
-    if (unwrappedValue.isPresent()) {
-      TypeMirror unwrappedValueType =
-          getOnlyElement(getAnnotationValuesWithDefaults(mapKey).keySet()).getReturnType();
-      return annotationExpression.getValueExpression(unwrappedValueType, unwrappedValue.get());
-    } else {
-      return annotationExpression.getAnnotationInstanceExpression();
-    }
-  }
-
-  /**
-   * Returns the {@link ClassName} in which {@link #mapKeyFactoryMethod(ContributionBinding,
-   * DaggerTypes, DaggerElements)} is generated.
-   */
-  static ClassName mapKeyProxyClassName(ContributionBinding binding) {
-    return elementBasedClassName(
-        MoreElements.asExecutable(binding.bindingElement().get()), "MapKey");
-  }
-
-  /**
-   * A {@code static create()} method to be added to {@link
-   * #mapKeyProxyClassName(ContributionBinding)} when the {@code @MapKey} annotation is not publicly
-   * accessible.
-   */
-  static Optional<MethodSpec> mapKeyFactoryMethod(
-      ContributionBinding binding, DaggerTypes types, DaggerElements elements) {
-    return binding
-        .mapKeyAnnotation()
-        .filter(mapKey -> !isMapKeyPubliclyAccessible(mapKey))
-        .map(
-            mapKey ->
-                methodBuilder("create")
-                    .addModifiers(PUBLIC, STATIC)
-                    .returns(TypeName.get(mapKeyType(mapKey, types)))
-                    .addStatement("return $L", directMapKeyExpression(mapKey, elements))
-                    .build());
-  }
-
-  private MapKeys() {}
-}
diff --git a/java/dagger/internal/codegen/MapMultibindingValidator.java b/java/dagger/internal/codegen/MapMultibindingValidator.java
deleted file mode 100644
index 346d271..0000000
--- a/java/dagger/internal/codegen/MapMultibindingValidator.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Multimaps.filterKeys;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSetMultimap;
-import static dagger.internal.codegen.Formatter.INDENT;
-import static dagger.model.BindingKind.MULTIBOUND_MAP;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import dagger.model.BindingGraph;
-import dagger.model.Key;
-import dagger.producers.Producer;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.lang.model.type.DeclaredType;
-
-/**
- * Reports an error for any map binding with either more than one contribution with the same map key
- * or contributions with inconsistent map key annotation types.
- */
-final class MapMultibindingValidator implements BindingGraphPlugin {
-
-  private final BindingDeclarationFormatter bindingDeclarationFormatter;
-  private final KeyFactory keyFactory;
-
-  @Inject
-  MapMultibindingValidator(
-      BindingDeclarationFormatter bindingDeclarationFormatter, KeyFactory keyFactory) {
-    this.bindingDeclarationFormatter = bindingDeclarationFormatter;
-    this.keyFactory = keyFactory;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/MapKeys";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    mapMultibindings(bindingGraph)
-        .forEach(
-            binding -> {
-              ImmutableSet<ContributionBinding> contributions =
-                  mapBindingContributions(binding, bindingGraph);
-              checkForDuplicateMapKeys(binding, contributions, diagnosticReporter);
-              checkForInconsistentMapKeyAnnotationTypes(binding, contributions, diagnosticReporter);
-            });
-  }
-
-  /**
-   * Returns the map multibindings in the binding graph. If a graph contains bindings for more than
-   * one of the following for the same {@code K} and {@code V}, then only the first one found will
-   * be returned so we don't report the same map contribution problem more than once.
-   *
-   * <ol>
-   *   <li>{@code Map<K, V>}
-   *   <li>{@code Map<K, Provider<V>>}
-   *   <li>{@code Map<K, Producer<V>>}
-   * </ol>
-   */
-  private ImmutableSet<dagger.model.Binding> mapMultibindings(BindingGraph bindingGraph) {
-    ImmutableSetMultimap<Key, dagger.model.Binding> mapMultibindings =
-        bindingGraph.bindings().stream()
-            .filter(node -> node.kind().equals(MULTIBOUND_MAP))
-            .collect(toImmutableSetMultimap(dagger.model.Binding::key, node -> node));
-
-    // Mutlbindings for Map<K, V>
-    SetMultimap<Key, dagger.model.Binding> plainValueMapMultibindings =
-        filterKeys(mapMultibindings, key -> !MapType.from(key).valuesAreFrameworkType());
-
-    // Multibindings for Map<K, Provider<V>> where Map<K, V> isn't in plainValueMapMultibindings
-    SetMultimap<Key, dagger.model.Binding> providerValueMapMultibindings =
-        filterKeys(
-            mapMultibindings,
-            key ->
-                MapType.from(key).valuesAreTypeOf(Provider.class)
-                    && !plainValueMapMultibindings.containsKey(keyFactory.unwrapMapValueType(key)));
-
-    // Multibindings for Map<K, Producer<V>> where Map<K, V> isn't in plainValueMapMultibindings and
-    // Map<K, Provider<V>> isn't in providerValueMapMultibindings
-    SetMultimap<Key, dagger.model.Binding> producerValueMapMultibindings =
-        filterKeys(
-            mapMultibindings,
-            key ->
-                MapType.from(key).valuesAreTypeOf(Producer.class)
-                    && !plainValueMapMultibindings.containsKey(keyFactory.unwrapMapValueType(key))
-                    && !providerValueMapMultibindings.containsKey(
-                        keyFactory.rewrapMapKey(key, Producer.class, Provider.class).get()));
-
-    return new ImmutableSet.Builder<dagger.model.Binding>()
-        .addAll(plainValueMapMultibindings.values())
-        .addAll(providerValueMapMultibindings.values())
-        .addAll(producerValueMapMultibindings.values())
-        .build();
-  }
-
-  private ImmutableSet<ContributionBinding> mapBindingContributions(
-      dagger.model.Binding binding, BindingGraph bindingGraph) {
-    checkArgument(binding.kind().equals(MULTIBOUND_MAP));
-    return bindingGraph.requestedBindings(binding).stream()
-        .map(b -> (BindingNode) b)
-        .map(b -> (ContributionBinding) b.delegate())
-        .collect(toImmutableSet());
-  }
-
-  private void checkForDuplicateMapKeys(
-      dagger.model.Binding multiboundMapBinding,
-      ImmutableSet<ContributionBinding> contributions,
-      DiagnosticReporter diagnosticReporter) {
-    ImmutableSetMultimap<Object, ContributionBinding> contributionsByMapKey =
-        ImmutableSetMultimap.copyOf(Multimaps.index(contributions, ContributionBinding::mapKey));
-
-    for (Set<ContributionBinding> contributionsForOneMapKey :
-        Multimaps.asMap(contributionsByMapKey).values()) {
-      if (contributionsForOneMapKey.size() > 1) {
-        diagnosticReporter.reportBinding(
-            ERROR,
-            multiboundMapBinding,
-            duplicateMapKeyErrorMessage(contributionsForOneMapKey, multiboundMapBinding.key()));
-      }
-    }
-  }
-
-  private void checkForInconsistentMapKeyAnnotationTypes(
-      dagger.model.Binding multiboundMapBinding,
-      ImmutableSet<ContributionBinding> contributions,
-      DiagnosticReporter diagnosticReporter) {
-    ImmutableSetMultimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding>
-        contributionsByMapKeyAnnotationType = indexByMapKeyAnnotationType(contributions);
-
-    if (contributionsByMapKeyAnnotationType.keySet().size() > 1) {
-      diagnosticReporter.reportBinding(
-          ERROR,
-          multiboundMapBinding,
-          inconsistentMapKeyAnnotationTypesErrorMessage(
-              contributionsByMapKeyAnnotationType, multiboundMapBinding.key()));
-    }
-  }
-
-  private static ImmutableSetMultimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding>
-      indexByMapKeyAnnotationType(ImmutableSet<ContributionBinding> contributions) {
-    return ImmutableSetMultimap.copyOf(
-        Multimaps.index(
-            contributions,
-            mapBinding ->
-                MoreTypes.equivalence()
-                    .wrap(mapBinding.mapKeyAnnotation().get().getAnnotationType())));
-  }
-
-  private String inconsistentMapKeyAnnotationTypesErrorMessage(
-      ImmutableSetMultimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding>
-          contributionsByMapKeyAnnotationType,
-      Key mapBindingKey) {
-    StringBuilder message =
-        new StringBuilder(mapBindingKey.toString())
-            .append(" uses more than one @MapKey annotation type");
-    Multimaps.asMap(contributionsByMapKeyAnnotationType)
-        .forEach(
-            (annotationType, contributions) -> {
-              message.append('\n').append(INDENT).append(annotationType.get()).append(':');
-              bindingDeclarationFormatter.formatIndentedList(message, contributions, 2);
-            });
-    return message.toString();
-  }
-
-  private String duplicateMapKeyErrorMessage(
-      Set<ContributionBinding> contributionsForOneMapKey, Key mapBindingKey) {
-    StringBuilder message =
-        new StringBuilder("The same map key is bound more than once for ").append(mapBindingKey);
-    bindingDeclarationFormatter.formatIndentedList(message, contributionsForOneMapKey, 1);
-    return message.toString();
-  }
-}
diff --git a/java/dagger/internal/codegen/MapType.java b/java/dagger/internal/codegen/MapType.java
deleted file mode 100644
index 73ecdbf..0000000
--- a/java/dagger/internal/codegen/MapType.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkState;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import dagger.model.Key;
-import java.util.Map;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Information about a {@link Map} {@link TypeMirror}.
- */
-@AutoValue
-abstract class MapType {
-  /**
-   * The map type itself, wrapped using {@link MoreTypes#equivalence()}. Use
-   * {@link #declaredMapType()} instead.
-   */
-  protected abstract Equivalence.Wrapper<DeclaredType> wrappedDeclaredMapType();
-
-  /**
-   * The map type itself.
-   */
-  DeclaredType declaredMapType() {
-    return wrappedDeclaredMapType().get();
-  }
-
-  /**
-   * {@code true} if the map type is the raw {@link Map} type.
-   */
-  boolean isRawType() {
-    return declaredMapType().getTypeArguments().isEmpty();
-  }
-
-  /**
-   * The map key type.
-   * 
-   * @throws IllegalStateException if {@link #isRawType()} is true.
-   */
-  TypeMirror keyType() {
-    checkState(!isRawType());
-    return declaredMapType().getTypeArguments().get(0);
-  }
-
-  /**
-   * The map value type.
-   * 
-   * @throws IllegalStateException if {@link #isRawType()} is true.
-   */
-  TypeMirror valueType() {
-    checkState(!isRawType());
-    return declaredMapType().getTypeArguments().get(1);
-  }
-
-  /**
-   * {@code true} if {@link #valueType()} is a {@code clazz}.
-   * 
-   * @throws IllegalStateException if {@link #isRawType()} is true.
-   */
-  boolean valuesAreTypeOf(Class<?> clazz) {
-    return MoreTypes.isType(valueType()) && MoreTypes.isTypeOf(clazz, valueType());
-  }
-
-  /**
-   * Returns {@code true} if the {@linkplain #valueType() value type} of the {@link Map} is a
-   * {@linkplain FrameworkTypes#isFrameworkType(TypeMirror) framework type}.
-   */
-  boolean valuesAreFrameworkType() {
-    return FrameworkTypes.isFrameworkType(valueType());
-  }
-
-  /**
-   * {@code V} if {@link #valueType()} is a framework type like {@code Provider<V>} or {@code
-   * Producer<V>}.
-   *
-   * @throws IllegalStateException if {@link #isRawType()} is true or {@link #valueType()} is not a
-   *     framework type
-   */
-  TypeMirror unwrappedFrameworkValueType() {
-    checkState(
-        valuesAreFrameworkType(), "called unwrappedFrameworkValueType() on %s", declaredMapType());
-    return uncheckedUnwrappedValueType();
-  }
-
-  /**
-   * {@code V} if {@link #valueType()} is a {@code WrappingClass<V>}.
-   *
-   * @throws IllegalStateException if {@link #isRawType()} is true or {@link #valueType()} is not a
-   *     {@code WrappingClass<V>}
-   * @throws IllegalArgumentException if {@code wrappingClass} does not have exactly one type
-   *     parameter
-   */
-  TypeMirror unwrappedValueType(Class<?> wrappingClass) {
-    checkArgument(
-        wrappingClass.getTypeParameters().length == 1,
-        "%s must have exactly one type parameter",
-        wrappingClass);
-    checkState(valuesAreTypeOf(wrappingClass), "expected values to be %s: %s", wrappingClass, this);
-    return uncheckedUnwrappedValueType();
-  }
-
-  private TypeMirror uncheckedUnwrappedValueType() {
-    return MoreTypes.asDeclared(valueType()).getTypeArguments().get(0);
-  }
-
-  /**
-   * {@code true} if {@code type} is a {@link Map} type.
-   */
-  static boolean isMap(TypeMirror type) {
-    return MoreTypes.isType(type) && MoreTypes.isTypeOf(Map.class, type);
-  }
-
-  /**
-   * {@code true} if {@code key.type()} is a {@link Map} type.
-   */
-  static boolean isMap(Key key) {
-    return isMap(key.type());
-  }
-
-  /**
-   * Returns a {@link MapType} for {@code type}.
-   *
-   * @throws IllegalArgumentException if {@code type} is not a {@link Map} type
-   */
-  static MapType from(TypeMirror type) {
-    checkArgument(isMap(type), "%s is not a Map", type);
-    return new AutoValue_MapType(MoreTypes.equivalence().wrap(MoreTypes.asDeclared(type)));
-  }
-
-  /**
-   * Returns a {@link MapType} for {@code key}'s {@link Key#type() type}.
-   *
-   * @throws IllegalArgumentException if {@code key.type()} is not a {@link Map} type
-   */
-  static MapType from(Key key) {
-    return from(key.type());
-  }
-}
diff --git a/java/dagger/internal/codegen/MemberSelect.java b/java/dagger/internal/codegen/MemberSelect.java
deleted file mode 100644
index c42c7c9..0000000
--- a/java/dagger/internal/codegen/MemberSelect.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.SINGLETON_INSTANCE;
-import static dagger.internal.codegen.SourceFiles.bindingTypeElementTypeVariableNames;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-import static dagger.internal.codegen.SourceFiles.setFactoryClassName;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER;
-import static dagger.internal.codegen.javapoet.TypeNames.PRODUCERS;
-import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static javax.lang.model.type.TypeKind.DECLARED;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableList;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import java.util.List;
-import java.util.Optional;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Represents a {@link com.sun.source.tree.MemberSelectTree} as a {@link CodeBlock}.
- */
-abstract class MemberSelect {
-
-  /**
-   * Returns a {@link MemberSelect} that accesses the field given by {@code fieldName} owned by
-   * {@code owningClass}.  In this context "local" refers to the fact that the field is owned by the
-   * type (or an enclosing type) from which the code block will be used.  The returned
-   * {@link MemberSelect} will not be valid for accessing the field from a different class
-   * (regardless of accessibility).
-   */
-  static MemberSelect localField(ClassName owningClass, String fieldName) {
-    return new LocalField(owningClass, fieldName);
-  }
-
-  private static final class LocalField extends MemberSelect {
-    final String fieldName;
-
-    LocalField(ClassName owningClass, String fieldName) {
-      super(owningClass, false);
-      this.fieldName = checkNotNull(fieldName);
-    }
-
-    @Override
-    CodeBlock getExpressionFor(ClassName usingClass) {
-      return owningClass().equals(usingClass)
-          ? CodeBlock.of("$N", fieldName)
-          : CodeBlock.of("$T.this.$N", owningClass(), fieldName);
-    }
-  }
-
-  /**
-   * Returns a {@link MemberSelect} that accesses the method given by {@code methodName} owned by
-   * {@code owningClass}. In this context "local" refers to the fact that the method is owned by the
-   * type (or an enclosing type) from which the code block will be used. The returned {@link
-   * MemberSelect} will not be valid for accessing the method from a different class (regardless of
-   * accessibility).
-   */
-  static MemberSelect localMethod(ClassName owningClass, String methodName) {
-    return new LocalMethod(owningClass, methodName);
-  }
-
-  private static final class LocalMethod extends MemberSelect {
-    final String methodName;
-
-    LocalMethod(ClassName owningClass, String methodName) {
-      super(owningClass, false);
-      this.methodName = checkNotNull(methodName);
-    }
-
-    @Override
-    CodeBlock getExpressionFor(ClassName usingClass) {
-      return owningClass().equals(usingClass)
-          ? CodeBlock.of("$N()", methodName)
-          : CodeBlock.of("$T.this.$N()", owningClass(), methodName);
-    }
-  }
-
-  /**
-   * If {@code resolvedBindings} is an unscoped provision binding with no factory arguments or a
-   * no-op members injection binding, then we don't need a field to hold its factory. In that case,
-   * this method returns the static member select that returns the factory or no-op members
-   * injector.
-   */
-  static Optional<MemberSelect> staticFactoryCreation(ResolvedBindings resolvedBindings) {
-    if (resolvedBindings.contributionBindings().isEmpty()) {
-      throw new AssertionError(
-          "Expected a contribution binding, but none found. *THIS IS A DAGGER BUG* - please "
-              + "report it on Github with as much context as you can provide. Thanks!"
-              + "\n\nKey: "
-              + resolvedBindings.key()
-              + "\nMultibinding declarations: "
-              + resolvedBindings.multibindingDeclarations()
-              + "\nSubcomponent declarations: "
-              + resolvedBindings.subcomponentDeclarations()
-              + "\nOptional binding declarations: "
-              + resolvedBindings.optionalBindingDeclarations());
-    }
-    ContributionBinding contributionBinding = resolvedBindings.contributionBinding();
-    if (contributionBinding.factoryCreationStrategy().equals(SINGLETON_INSTANCE)
-        && !contributionBinding.scope().isPresent()) {
-      switch (contributionBinding.kind()) {
-        case MULTIBOUND_MAP:
-          return Optional.of(emptyMapFactory(contributionBinding));
-
-        case MULTIBOUND_SET:
-          return Optional.of(emptySetFactory(contributionBinding));
-
-        case INJECTION:
-        case PROVISION:
-          TypeMirror keyType = resolvedBindings.key().type();
-          if (keyType.getKind().equals(DECLARED)) {
-            ImmutableList<TypeVariableName> typeVariables =
-                bindingTypeElementTypeVariableNames(contributionBinding);
-            if (!typeVariables.isEmpty()) {
-              List<? extends TypeMirror> typeArguments =
-                  ((DeclaredType) keyType).getTypeArguments();
-              return Optional.of(
-                  MemberSelect.parameterizedFactoryCreateMethod(
-                      generatedClassNameForBinding(contributionBinding), typeArguments));
-            }
-          }
-          // fall through
-
-        default:
-          return Optional.of(
-              new StaticMethod(
-                  generatedClassNameForBinding(contributionBinding), CodeBlock.of("create()")));
-      }
-    }
-
-    return Optional.empty();
-  }
-
-  /**
-   * Returns a {@link MemberSelect} for the instance of a {@code create()} method on a factory. This
-   * only applies for factories that do not have any dependencies.
-   */
-  private static MemberSelect parameterizedFactoryCreateMethod(
-      ClassName owningClass, List<? extends TypeMirror> parameters) {
-    return new ParameterizedStaticMethod(
-        owningClass, ImmutableList.copyOf(parameters), CodeBlock.of("create()"), FACTORY);
-  }
-
-  private static final class StaticMethod extends MemberSelect {
-    final CodeBlock methodCodeBlock;
-
-    StaticMethod(ClassName owningClass, CodeBlock methodCodeBlock) {
-      super(owningClass, true);
-      this.methodCodeBlock = checkNotNull(methodCodeBlock);
-    }
-
-    @Override
-    CodeBlock getExpressionFor(ClassName usingClass) {
-      return owningClass().equals(usingClass)
-          ? methodCodeBlock
-          : CodeBlock.of("$T.$L", owningClass(), methodCodeBlock);
-    }
-  }
-
-  /** A {@link MemberSelect} for a factory of an empty map. */
-  private static MemberSelect emptyMapFactory(ContributionBinding contributionBinding) {
-    BindingType bindingType = contributionBinding.bindingType();
-    ImmutableList<TypeMirror> typeParameters =
-        ImmutableList.copyOf(
-            MoreTypes.asDeclared(contributionBinding.key().type()).getTypeArguments());
-    if (bindingType.equals(BindingType.PRODUCTION)) {
-      return new ParameterizedStaticMethod(
-          PRODUCERS, typeParameters, CodeBlock.of("emptyMapProducer()"), PRODUCER);
-    } else {
-      return new ParameterizedStaticMethod(
-          MAP_FACTORY, typeParameters, CodeBlock.of("emptyMapProvider()"), PROVIDER);
-    }
-  }
-
-  /**
-   * A static member select for an empty set factory. Calls {@link
-   * dagger.internal.SetFactory#empty()}, {@link dagger.producers.internal.SetProducer#empty()}, or
-   * {@link dagger.producers.internal.SetOfProducedProducer#empty()}, depending on the set bindings.
-   */
-  private static MemberSelect emptySetFactory(ContributionBinding binding) {
-    return new ParameterizedStaticMethod(
-        setFactoryClassName(binding),
-        ImmutableList.of(SetType.from(binding.key()).elementType()),
-        CodeBlock.of("empty()"),
-        FACTORY);
-  }
-
-  private static final class ParameterizedStaticMethod extends MemberSelect {
-    final ImmutableList<TypeMirror> typeParameters;
-    final CodeBlock methodCodeBlock;
-    final ClassName rawReturnType;
-
-    ParameterizedStaticMethod(
-        ClassName owningClass,
-        ImmutableList<TypeMirror> typeParameters,
-        CodeBlock methodCodeBlock,
-        ClassName rawReturnType) {
-      super(owningClass, true);
-      this.typeParameters = typeParameters;
-      this.methodCodeBlock = methodCodeBlock;
-      this.rawReturnType = rawReturnType;
-    }
-
-    @Override
-    CodeBlock getExpressionFor(ClassName usingClass) {
-      boolean accessible = true;
-      for (TypeMirror typeParameter : typeParameters) {
-        accessible &= isTypeAccessibleFrom(typeParameter, usingClass.packageName());
-      }
-
-      if (accessible) {
-        return CodeBlock.of(
-            "$T.<$L>$L",
-            owningClass(),
-            typeParameters.stream().map(CodeBlocks::type).collect(toParametersCodeBlock()),
-            methodCodeBlock);
-      } else {
-        return CodeBlock.of("(($T) $T.$L)", rawReturnType, owningClass(), methodCodeBlock);
-      }
-    }
-  }
-
-  private final ClassName owningClass;
-  private final boolean staticMember;
-
-  MemberSelect(ClassName owningClass, boolean staticMemeber) {
-    this.owningClass = owningClass;
-    this.staticMember = staticMemeber;
-  }
-
-  /** Returns the class that owns the member being selected. */
-  ClassName owningClass() {
-    return owningClass;
-  }
-
-  /**
-   * Returns true if the member being selected is static and does not require an instance of
-   * {@link #owningClass()}.
-   */
-  boolean staticMember() {
-    return staticMember;
-  }
-
-  /**
-   * Returns a {@link CodeBlock} suitable for accessing the member from the given {@code
-   * usingClass}.
-   */
-  abstract CodeBlock getExpressionFor(ClassName usingClass);
-}
diff --git a/java/dagger/internal/codegen/MembersInjectionBinding.java b/java/dagger/internal/codegen/MembersInjectionBinding.java
deleted file mode 100644
index 4918fa1..0000000
--- a/java/dagger/internal/codegen/MembersInjectionBinding.java
+++ /dev/null
@@ -1,140 +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.auto.common.MoreElements.isAnnotationPresent;
-import static java.util.stream.Collectors.toList;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-
-/**
- * Represents the full members injection of a particular type.
- */
-@AutoValue
-abstract class MembersInjectionBinding extends Binding {
-  @Override
-  public final Optional<Element> bindingElement() {
-    return Optional.of(membersInjectedType());
-  }
-
-  abstract TypeElement membersInjectedType();
-
-  @Override
-  abstract Optional<MembersInjectionBinding> unresolved();
-
-  @Override
-  public Optional<TypeElement> contributingModule() {
-    return Optional.empty();
-  }
-
-  /** The set of individual sites where {@link Inject} is applied. */
-  abstract ImmutableSortedSet<InjectionSite> injectionSites();
-
-  @Override
-  BindingType bindingType() {
-    return BindingType.MEMBERS_INJECTION;
-  }
-
-  @Override
-  public BindingKind kind() {
-    return BindingKind.MEMBERS_INJECTION;
-  }
-
-  @Override
-  public boolean isNullable() {
-    return false;
-  }
-
-  /**
-   * Returns {@code true} if any of this binding's injection sites are directly on the bound type.
-   */
-  boolean hasLocalInjectionSites() {
-    return injectionSites()
-        .stream()
-        .anyMatch(
-            injectionSite ->
-                injectionSite.element().getEnclosingElement().equals(membersInjectedType()));
-  }
-
-  @Override
-  boolean requiresModuleInstance() {
-    return false;
-  }
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  // TODO(ronshapiro,dpb): simplify the equality semantics
-  @Override
-  public abstract boolean equals(Object obj);
-
-  @AutoValue
-  abstract static class InjectionSite {
-    enum Kind {
-      FIELD,
-      METHOD,
-    }
-
-    abstract Kind kind();
-
-    abstract Element element();
-
-    abstract ImmutableSet<DependencyRequest> dependencies();
-
-    /**
-     * Returns the index of {@link #element()} in its parents {@code @Inject} members that have the
-     * same simple name. This method filters out private elements so that the results will be
-     * consistent independent of whether the build system uses header jars or not.
-     */
-    @Memoized
-    int indexAmongAtInjectMembersWithSameSimpleName() {
-      return element()
-          .getEnclosingElement()
-          .getEnclosedElements()
-          .stream()
-          .filter(element -> isAnnotationPresent(element, Inject.class))
-          .filter(element -> !element.getModifiers().contains(Modifier.PRIVATE))
-          .filter(element -> element.getSimpleName().equals(this.element().getSimpleName()))
-          .collect(toList())
-          .indexOf(element());
-    }
-
-    static InjectionSite field(VariableElement element, DependencyRequest dependency) {
-      return new AutoValue_MembersInjectionBinding_InjectionSite(
-          Kind.FIELD, element, ImmutableSet.of(dependency));
-    }
-
-    static InjectionSite method(
-        ExecutableElement element, Iterable<DependencyRequest> dependencies) {
-      return new AutoValue_MembersInjectionBinding_InjectionSite(
-          Kind.METHOD, element, ImmutableSet.copyOf(dependencies));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/MembersInjectionBindingExpression.java b/java/dagger/internal/codegen/MembersInjectionBindingExpression.java
deleted file mode 100644
index e9a8ffc..0000000
--- a/java/dagger/internal/codegen/MembersInjectionBindingExpression.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static javax.lang.model.type.TypeKind.VOID;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.ParameterSpec;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.javapoet.Expression;
-import javax.lang.model.element.ExecutableElement;
-
-/**
- * A binding expression for members injection component methods. See {@link
- * MembersInjectionMethods}.
- */
-final class MembersInjectionBindingExpression extends BindingExpression {
-  private final MembersInjectionBinding binding;
-  private final MembersInjectionMethods membersInjectionMethods;
-
-  MembersInjectionBindingExpression(
-      ResolvedBindings resolvedBindings, MembersInjectionMethods membersInjectionMethods) {
-    this.binding = resolvedBindings.membersInjectionBinding().get();
-    this.membersInjectionMethods = membersInjectionMethods;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    throw new UnsupportedOperationException(binding.toString());
-  }
-
-  // TODO(ronshapiro): This class doesn't need to be a BindingExpression, as
-  // getDependencyExpression() should never be called for members injection methods. It's probably
-  // better suited as a method on MembersInjectionMethods
-  @Override
-  protected CodeBlock getComponentMethodImplementation(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    ExecutableElement methodElement = componentMethod.methodElement();
-    ParameterSpec parameter = ParameterSpec.get(getOnlyElement(methodElement.getParameters()));
-
-    if (binding.injectionSites().isEmpty()) {
-      return methodElement.getReturnType().getKind().equals(VOID)
-          ? CodeBlock.of("")
-          : CodeBlock.of("return $N;", parameter);
-    } else {
-      return methodElement.getReturnType().getKind().equals(VOID)
-          ? CodeBlock.of("$L;", membersInjectionInvocation(parameter))
-          : CodeBlock.of("return $L;", membersInjectionInvocation(parameter));
-    }
-  }
-
-  CodeBlock membersInjectionInvocation(ParameterSpec target) {
-    return CodeBlock.of("$N($N)", membersInjectionMethods.getOrCreate(binding.key()), target);
-  }
-}
diff --git a/java/dagger/internal/codegen/MembersInjectionMethods.java b/java/dagger/internal/codegen/MembersInjectionMethods.java
deleted file mode 100644
index 1e04669..0000000
--- a/java/dagger/internal/codegen/MembersInjectionMethods.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.MEMBERS_INJECTION_METHOD;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.InjectionMethods.InjectionSiteMethod;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-/** Manages the member injection methods for a component. */
-final class MembersInjectionMethods {
-  private final Map<Key, MethodSpec> membersInjectionMethods = new LinkedHashMap<>();
-  private final ComponentImplementation componentImplementation;
-  private final ComponentBindingExpressions bindingExpressions;
-  private final BindingGraph graph;
-  private final DaggerElements elements;
-  private final DaggerTypes types;
-
-  MembersInjectionMethods(
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions bindingExpressions,
-      BindingGraph graph,
-      DaggerElements elements,
-      DaggerTypes types) {
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.bindingExpressions = checkNotNull(bindingExpressions);
-    this.graph = checkNotNull(graph);
-    this.elements = checkNotNull(elements);
-    this.types = checkNotNull(types);
-  }
-
-  /**
-   * Returns the members injection {@link MethodSpec} for the given {@link Key}, creating it if
-   * necessary.
-   */
-  MethodSpec getOrCreate(Key key) {
-    return reentrantComputeIfAbsent(membersInjectionMethods, key, this::membersInjectionMethod);
-  }
-
-  private MethodSpec membersInjectionMethod(Key key) {
-    ResolvedBindings resolvedBindings =
-        graph.membersInjectionBindings().getOrDefault(key, graph.contributionBindings().get(key));
-    Binding binding = resolvedBindings.binding();
-    TypeMirror keyType = binding.key().type();
-    TypeMirror membersInjectedType =
-        isTypeAccessibleFrom(keyType, componentImplementation.name().packageName())
-            ? keyType
-            : elements.getTypeElement(Object.class).asType();
-    TypeName membersInjectedTypeName = TypeName.get(membersInjectedType);
-    Name bindingTypeName = binding.bindingTypeElement().get().getSimpleName();
-    // TODO(ronshapiro): include type parameters in this name e.g. injectFooOfT, and outer class
-    // simple names Foo.Builder -> injectFooBuilder
-    String methodName = componentImplementation.getUniqueMethodName("inject" + bindingTypeName);
-    ParameterSpec parameter = ParameterSpec.builder(membersInjectedTypeName, "instance").build();
-    MethodSpec.Builder methodBuilder =
-        methodBuilder(methodName)
-            .addModifiers(PRIVATE)
-            .returns(membersInjectedTypeName)
-            .addParameter(parameter);
-    TypeElement canIgnoreReturnValue =
-        elements.getTypeElement("com.google.errorprone.annotations.CanIgnoreReturnValue");
-    if (canIgnoreReturnValue != null) {
-      methodBuilder.addAnnotation(ClassName.get(canIgnoreReturnValue));
-    }
-    CodeBlock instance = CodeBlock.of("$N", parameter);
-    methodBuilder.addCode(
-        InjectionSiteMethod.invokeAll(
-            injectionSites(binding),
-            componentImplementation.name(),
-            instance,
-            membersInjectedType,
-            types,
-            request ->
-                bindingExpressions
-                    .getDependencyArgumentExpression(request, componentImplementation.name())
-                    .codeBlock(),
-            elements));
-    methodBuilder.addStatement("return $L", instance);
-
-    MethodSpec method = methodBuilder.build();
-    componentImplementation.addMethod(MEMBERS_INJECTION_METHOD, method);
-    return method;
-  }
-
-  private static ImmutableSet<InjectionSite> injectionSites(Binding binding) {
-    if (binding instanceof ProvisionBinding) {
-      return ((ProvisionBinding) binding).injectionSites();
-    } else if (binding instanceof MembersInjectionBinding) {
-      return ((MembersInjectionBinding) binding).injectionSites();
-    }
-    throw new IllegalArgumentException(binding.key().toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/MembersInjectionValidator.java b/java/dagger/internal/codegen/MembersInjectionValidator.java
deleted file mode 100644
index 036315e..0000000
--- a/java/dagger/internal/codegen/MembersInjectionValidator.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.InjectionAnnotations.getQualifiers;
-
-import com.google.auto.common.MoreElements;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * Validates members injection requests (members injection methods on components and requests for
- * {@code MembersInjector<Foo>}).
- */
-final class MembersInjectionValidator {
-
-  @Inject
-  MembersInjectionValidator() {}
-
-  /** Reports errors if a request for a {@code MembersInjector<Foo>}) is invalid. */
-  ValidationReport<Element> validateMembersInjectionRequest(
-      Element requestElement, TypeMirror membersInjectedType) {
-    ValidationReport.Builder<Element> report = ValidationReport.about(requestElement);
-    checkQualifiers(report, requestElement);
-    membersInjectedType.accept(VALIDATE_MEMBERS_INJECTED_TYPE, report);
-    return report.build();
-  }
-
-  /**
-   * Reports errors if a members injection method on a component is invalid.
-   *
-   * @throws IllegalArgumentException if the method doesn't have exactly one parameter
-   */
-  ValidationReport<ExecutableElement> validateMembersInjectionMethod(
-      ExecutableElement method, TypeMirror membersInjectedType) {
-    checkArgument(
-        method.getParameters().size() == 1, "expected a method with one parameter: %s", method);
-
-    ValidationReport.Builder<ExecutableElement> report = ValidationReport.about(method);
-    checkQualifiers(report, method);
-    checkQualifiers(report, method.getParameters().get(0));
-    membersInjectedType.accept(VALIDATE_MEMBERS_INJECTED_TYPE, report);
-    return report.build();
-  }
-
-  private void checkQualifiers(ValidationReport.Builder<?> report, Element element) {
-    for (AnnotationMirror qualifier : getQualifiers(element)) {
-      report.addError("Cannot inject members into qualified types", element, qualifier);
-      break; // just report on the first qualifier, in case there is more than one
-    }
-  }
-
-  private static final TypeVisitor<Void, ValidationReport.Builder<?>>
-      VALIDATE_MEMBERS_INJECTED_TYPE =
-          new SimpleTypeVisitor8<Void, ValidationReport.Builder<?>>() {
-            // Only declared types can be members-injected.
-            @Override
-            protected Void defaultAction(TypeMirror type, ValidationReport.Builder<?> report) {
-              report.addError("Cannot inject members into " + type);
-              return null;
-            }
-
-            @Override
-            public Void visitDeclared(DeclaredType type, ValidationReport.Builder<?> report) {
-              if (type.getTypeArguments().isEmpty()) {
-                // If the type is the erasure of a generic type, that means the user referred to
-                // Foo<T> as just 'Foo', which we don't allow.  (This is a judgement call; we
-                // *could* allow it and instantiate the type bounds, but we don't.)
-                if (!MoreElements.asType(type.asElement()).getTypeParameters().isEmpty()) {
-                  report.addError("Cannot inject members into raw type " + type);
-                }
-              } else {
-                // If the type has arguments, validate that each type argument is declared.
-                // Otherwise the type argument may be a wildcard (or other type), and we can't
-                // resolve that to actual types.  For array type arguments, validate the type of the
-                // array.
-                for (TypeMirror arg : type.getTypeArguments()) {
-                  if (!arg.accept(DECLARED_OR_ARRAY, null)) {
-                    report.addError(
-                        "Cannot inject members into types with unbounded type arguments: " + type);
-                  }
-                }
-              }
-              return null;
-            }
-          };
-
-  // TODO(dpb): Can this be inverted so it explicitly rejects wildcards or type variables?
-  // This logic is hard to describe.
-  private static final TypeVisitor<Boolean, Void> DECLARED_OR_ARRAY =
-      new SimpleTypeVisitor8<Boolean, Void>(false) {
-        @Override
-        public Boolean visitArray(ArrayType arrayType, Void p) {
-          return arrayType
-              .getComponentType()
-              .accept(
-                  new SimpleTypeVisitor8<Boolean, Void>(false) {
-                    @Override
-                    public Boolean visitDeclared(DeclaredType declaredType, Void p) {
-                      for (TypeMirror arg : declaredType.getTypeArguments()) {
-                        if (!arg.accept(this, null)) {
-                          return false;
-                        }
-                      }
-                      return true;
-                    }
-
-                    @Override
-                    public Boolean visitArray(ArrayType arrayType, Void p) {
-                      return arrayType.getComponentType().accept(this, null);
-                    }
-
-                    @Override
-                    public Boolean visitPrimitive(PrimitiveType primitiveType, Void p) {
-                      return true;
-                    }
-                  },
-                  null);
-        }
-
-        @Override
-        public Boolean visitDeclared(DeclaredType t, Void p) {
-          return true;
-        }
-      };
-}
diff --git a/java/dagger/internal/codegen/MembersInjectorGenerator.java b/java/dagger/internal/codegen/MembersInjectorGenerator.java
deleted file mode 100644
index 4360af7..0000000
--- a/java/dagger/internal/codegen/MembersInjectorGenerator.java
+++ /dev/null
@@ -1,204 +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.checkState;
-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.GwtCompatibility.gwtIncompatibleAnnotation;
-import static dagger.internal.codegen.SourceFiles.bindingTypeElementTypeVariableNames;
-import static dagger.internal.codegen.SourceFiles.frameworkFieldUsages;
-import static dagger.internal.codegen.SourceFiles.generateBindingFieldsForDependencies;
-import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
-import static dagger.internal.codegen.SourceFiles.parameterizedGeneratedTypeNameForBinding;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.membersInjectorOf;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-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;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.MembersInjector;
-import dagger.internal.codegen.InjectionMethods.InjectionSiteMethod;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import java.util.Map.Entry;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-
-/**
- * Generates {@link MembersInjector} implementations from {@link MembersInjectionBinding} instances.
- */
-final class MembersInjectorGenerator extends SourceFileGenerator<MembersInjectionBinding> {
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  @Inject
-  MembersInjectorGenerator(
-      Filer filer, DaggerElements elements, DaggerTypes types, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-    this.types = types;
-    this.elements = elements;
-  }
-
-  @Override
-  ClassName nameGeneratedType(MembersInjectionBinding binding) {
-    return membersInjectorNameForType(binding.membersInjectedType());
-  }
-
-  @Override
-  Element originatingElement(MembersInjectionBinding binding) {
-    return binding.membersInjectedType();
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, MembersInjectionBinding binding) {
-    // Empty members injection bindings are special and don't need source files.
-    if (binding.injectionSites().isEmpty()) {
-      return Optional.empty();
-    }
-    // We don't want to write out resolved bindings -- we want to write out the generic version.
-    checkState(
-        !binding.unresolved().isPresent(),
-        "tried to generate a MembersInjector for a binding of a resolved generic type: %s",
-        binding);
-
-    ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding);
-    TypeSpec.Builder injectorTypeBuilder =
-        classBuilder(generatedTypeName)
-            .addModifiers(PUBLIC, FINAL)
-            .addTypeVariables(typeParameters);
-
-    TypeName injectedTypeName = TypeName.get(binding.key().type());
-    TypeName implementedType = membersInjectorOf(injectedTypeName);
-    injectorTypeBuilder.addSuperinterface(implementedType);
-
-    MethodSpec.Builder injectMembersBuilder =
-        methodBuilder("injectMembers")
-            .addModifiers(PUBLIC)
-            .addAnnotation(Override.class)
-            .addParameter(injectedTypeName, "instance");
-
-    ImmutableMap<Key, FrameworkField> fields = generateBindingFieldsForDependencies(binding);
-
-    ImmutableMap.Builder<Key, FieldSpec> dependencyFieldsBuilder = ImmutableMap.builder();
-
-    MethodSpec.Builder constructorBuilder = constructorBuilder().addModifiers(PUBLIC);
-
-    // We use a static create method so that generated components can avoid having
-    // to refer to the generic types of the factory.
-    // (Otherwise they may have visibility problems referring to the types.)
-    MethodSpec.Builder createMethodBuilder =
-        methodBuilder("create")
-            .returns(implementedType)
-            .addModifiers(PUBLIC, STATIC)
-            .addTypeVariables(typeParameters);
-
-    createMethodBuilder.addCode(
-        "return new $T(", parameterizedGeneratedTypeNameForBinding(binding));
-    ImmutableList.Builder<CodeBlock> constructorInvocationParameters = ImmutableList.builder();
-
-    boolean usesRawFrameworkTypes = false;
-    UniqueNameSet fieldNames = new UniqueNameSet();
-    for (Entry<Key, FrameworkField> fieldEntry : fields.entrySet()) {
-      Key dependencyKey = fieldEntry.getKey();
-      FrameworkField bindingField = fieldEntry.getValue();
-
-      // If the dependency type is not visible to this members injector, then use the raw framework
-      // type for the field.
-      boolean useRawFrameworkType =
-          !isTypeAccessibleFrom(dependencyKey.type(), generatedTypeName.packageName());
-
-      String fieldName = fieldNames.getUniqueName(bindingField.name());
-      TypeName fieldType = useRawFrameworkType ? bindingField.type().rawType : bindingField.type();
-      FieldSpec.Builder fieldBuilder = FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL);
-      ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(fieldType, fieldName);
-
-      // If we're using the raw type for the field, then suppress the injectMembers method's
-      // unchecked-type warning and the field's and the constructor and create-method's
-      // parameters' raw-type warnings.
-      if (useRawFrameworkType) {
-        usesRawFrameworkTypes = true;
-        fieldBuilder.addAnnotation(suppressWarnings(RAWTYPES));
-        parameterBuilder.addAnnotation(suppressWarnings(RAWTYPES));
-      }
-      constructorBuilder.addParameter(parameterBuilder.build());
-      createMethodBuilder.addParameter(parameterBuilder.build());
-
-      FieldSpec field = fieldBuilder.build();
-      injectorTypeBuilder.addField(field);
-      constructorBuilder.addStatement("this.$1N = $1N", field);
-      dependencyFieldsBuilder.put(dependencyKey, field);
-      constructorInvocationParameters.add(CodeBlock.of("$N", field));
-    }
-
-    createMethodBuilder.addCode(
-        constructorInvocationParameters.build().stream().collect(toParametersCodeBlock()));
-    createMethodBuilder.addCode(");");
-
-    injectorTypeBuilder.addMethod(constructorBuilder.build());
-    injectorTypeBuilder.addMethod(createMethodBuilder.build());
-
-    ImmutableMap<Key, FieldSpec> dependencyFields = dependencyFieldsBuilder.build();
-
-    injectMembersBuilder.addCode(
-        InjectionSiteMethod.invokeAll(
-            binding.injectionSites(),
-            generatedTypeName,
-            CodeBlock.of("instance"),
-            binding.key().type(),
-            types,
-            frameworkFieldUsages(binding.dependencies(), dependencyFields)::get,
-            elements));
-
-    if (usesRawFrameworkTypes) {
-      injectMembersBuilder.addAnnotation(suppressWarnings(UNCHECKED));
-    }
-    injectorTypeBuilder.addMethod(injectMembersBuilder.build());
-
-    for (InjectionSite injectionSite : binding.injectionSites()) {
-      if (injectionSite.element().getEnclosingElement().equals(binding.membersInjectedType())) {
-        injectorTypeBuilder.addMethod(
-            InjectionSiteMethod.create(injectionSite, elements).toMethodSpec());
-      }
-    }
-
-    gwtIncompatibleAnnotation(binding).ifPresent(injectorTypeBuilder::addAnnotation);
-
-    return Optional.of(injectorTypeBuilder);
-  }
-}
diff --git a/java/dagger/internal/codegen/MembersInjectorProviderCreationExpression.java b/java/dagger/internal/codegen/MembersInjectorProviderCreationExpression.java
deleted file mode 100644
index 8e863e5..0000000
--- a/java/dagger/internal/codegen/MembersInjectorProviderCreationExpression.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
-import static dagger.internal.codegen.javapoet.TypeNames.INSTANCE_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.MEMBERS_INJECTORS;
-
-import com.google.auto.common.MoreTypes;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import javax.lang.model.type.TypeMirror;
-
-/** A {@code Provider<MembersInjector<Foo>>} creation expression. */
-final class MembersInjectorProviderCreationExpression
-    implements FrameworkInstanceCreationExpression {
-
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final ProvisionBinding binding;
-
-  MembersInjectorProviderCreationExpression(
-      ProvisionBinding binding, ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    TypeMirror membersInjectedType =
-        getOnlyElement(MoreTypes.asDeclared(binding.key().type()).getTypeArguments());
-
-    CodeBlock membersInjector =
-        binding.injectionSites().isEmpty()
-            ? CodeBlock.of("$T.<$T>noOp()", MEMBERS_INJECTORS, membersInjectedType)
-            : CodeBlock.of(
-                "$T.create($L)",
-                membersInjectorNameForType(MoreTypes.asTypeElement(membersInjectedType)),
-                componentBindingExpressions.getCreateMethodArgumentsCodeBlock(binding));
-
-    // TODO(ronshapiro): consider adding a MembersInjectorBindingExpression to return this directly
-    // (as it's rarely requested as a Provider).
-    return CodeBlock.of("$T.create($L)", INSTANCE_FACTORY, membersInjector);
-  }
-
-  @Override
-  public boolean useInnerSwitchingProvider() {
-    return !binding.injectionSites().isEmpty();
-  }
-}
diff --git a/java/dagger/internal/codegen/MethodBindingExpression.java b/java/dagger/internal/codegen/MethodBindingExpression.java
deleted file mode 100644
index 2120e80..0000000
--- a/java/dagger/internal/codegen/MethodBindingExpression.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static dagger.internal.codegen.ComponentImplementation.FieldSpecKind.PRIVATE_METHOD_SCOPED_FIELD;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.VOLATILE;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.DoubleCheck;
-import dagger.internal.MemoizedSentinel;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.RequestKind;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/** A binding expression that wraps another in a nullary method on the component. */
-abstract class MethodBindingExpression extends BindingExpression {
-  private final BindingRequest request;
-  private final ResolvedBindings resolvedBindings;
-  private final ContributionBinding binding;
-  private final BindingMethodImplementation bindingMethodImplementation;
-  private final ComponentImplementation componentImplementation;
-  private final ProducerEntryPointView producerEntryPointView;
-  private final BindingExpression wrappedBindingExpression;
-  private final DaggerTypes types;
-
-  protected MethodBindingExpression(
-      BindingRequest request,
-      ResolvedBindings resolvedBindings,
-      MethodImplementationStrategy methodImplementationStrategy,
-      BindingExpression wrappedBindingExpression,
-      ComponentImplementation componentImplementation,
-      DaggerTypes types) {
-    this.request = checkNotNull(request);
-    this.resolvedBindings = resolvedBindings;
-    this.binding = resolvedBindings.contributionBinding();
-    this.bindingMethodImplementation = bindingMethodImplementation(methodImplementationStrategy);
-    this.wrappedBindingExpression = checkNotNull(wrappedBindingExpression);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.producerEntryPointView = new ProducerEntryPointView(types);
-    this.types = checkNotNull(types);
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    if (request.frameworkType().isPresent()) {
-      // Initializing a framework instance that participates in a cycle requires that the underlying
-      // FrameworkInstanceBindingExpression is invoked in order for a cycle to be detected properly.
-      // When a MethodBindingExpression wraps a FrameworkInstanceBindingExpression, the wrapped
-      // expression will only be invoked once to implement the method body. This is a hack to work
-      // around that weirdness - methodImplementation.body() will invoke the framework instance
-      // initialization again in case the field is not fully initialized.
-      // TODO(b/121196706): use a less hacky approach to fix this bug
-      Object unused = methodBody();
-    }
-    
-    addMethod();
-    return Expression.create(
-        returnType(),
-        requestingClass.equals(componentImplementation.name())
-            ? CodeBlock.of("$N()", methodName())
-            : CodeBlock.of("$T.this.$N()", componentImplementation.name(), methodName()));
-  }
-
-  @Override
-  final CodeBlock getModifiableBindingMethodImplementation(
-      ModifiableBindingMethod modifiableBindingMethod,
-      ComponentImplementation component,
-      DaggerTypes types) {
-    // A matching modifiable binding method means that we have previously created the binding method
-    // and we are now implementing it. If there is no matching method we need to first create the
-    // method. We create the method by deferring to getDependencyExpression (defined above) via a
-    // call to super.getModifiableBindingMethodImplementation().
-    if (supertypeModifiableBindingMethod().isPresent()) {
-      checkState(
-          supertypeModifiableBindingMethod().get().fulfillsSameRequestAs(modifiableBindingMethod));
-      return methodBody();
-    }
-    return super.getModifiableBindingMethodImplementation(
-        modifiableBindingMethod, component, types);
-  }
-
-  protected final Optional<ModifiableBindingMethod> supertypeModifiableBindingMethod() {
-    return componentImplementation.supertypeModifiableBindingMethod(request);
-  }
-
-  @Override
-  Expression getDependencyExpressionForComponentMethod(ComponentMethodDescriptor componentMethod,
-      ComponentImplementation component) {
-    return producerEntryPointView
-        .getProducerEntryPointField(this, componentMethod, component)
-        .orElseGet(
-            () -> super.getDependencyExpressionForComponentMethod(componentMethod, component));
-  }
-
-  /** Adds the method to the component (if necessary) the first time it's called. */
-  protected abstract void addMethod();
-
-  /** Returns the name of the method to call. */
-  protected abstract String methodName();
-
-  /**
-   * Returns {@code true} if the method of this binding expression is modifiable and is not a
-   * component method.
-   */
-  protected boolean isModifiableImplementationMethod() {
-    return false;
-  }
-
-  /** The method's body. */
-  protected final CodeBlock methodBody() {
-    return implementation(
-        wrappedBindingExpression.getDependencyExpression(componentImplementation.name())
-            ::codeBlock);
-  }
-
-  /** The method's body if this method is a component method. */
-  protected final CodeBlock methodBodyForComponentMethod(
-      ComponentMethodDescriptor componentMethod) {
-    return implementation(
-        wrappedBindingExpression.getDependencyExpressionForComponentMethod(
-                componentMethod, componentImplementation)
-            ::codeBlock);
-  }
-
-  private CodeBlock implementation(Supplier<CodeBlock> simpleBindingExpression) {
-    return bindingMethodImplementation.implementation(simpleBindingExpression);
-  }
-
-  private BindingMethodImplementation bindingMethodImplementation(
-      MethodImplementationStrategy methodImplementationStrategy) {
-    switch (methodImplementationStrategy) {
-      case SIMPLE:
-        return new SimpleMethodImplementation();
-      case SINGLE_CHECK:
-        return new SingleCheckedMethodImplementation();
-      case DOUBLE_CHECK:
-        return new DoubleCheckedMethodImplementation();
-    }
-    throw new AssertionError(methodImplementationStrategy);
-  }
-
-  /** Returns the return type for the dependency request. */
-  protected TypeMirror returnType() {
-    if (request.isRequestKind(RequestKind.INSTANCE)
-        && binding.contributedPrimitiveType().isPresent()) {
-      return binding.contributedPrimitiveType().get();
-    }
-
-    if (matchingComponentMethod().isPresent()) {
-      // Component methods are part of the user-defined API, and thus we must use the user-defined
-      // type.
-      return matchingComponentMethod().get().resolvedReturnType(types);
-    }
-
-    // If the component is abstract, this method may be overridden by another implementation in a
-    // different package for which requestedType is inaccessible. In order to make that method
-    // overridable, we use the publicly accessible type. If the method is private, we don't need to
-    // worry about this, and instead just need to check accessibility of the file we're about to
-    // write
-    TypeMirror requestedType = request.requestedType(binding.contributedType(), types);
-    return isModifiableImplementationMethod()
-        ? types.publiclyAccessibleType(requestedType)
-        : types.accessibleType(requestedType, componentImplementation.name());
-  }
-
-  private Optional<ComponentMethodDescriptor> matchingComponentMethod() {
-    return componentImplementation.componentDescriptor().firstMatchingComponentMethod(request);
-  }
-
-  /** Strateg for implementing the body of this method. */
-  enum MethodImplementationStrategy {
-    SIMPLE,
-    SINGLE_CHECK,
-    DOUBLE_CHECK,
-    ;
-  }
-
-  private abstract static class BindingMethodImplementation {
-    /**
-     * Returns the method body, which contains zero or more statements (including semicolons).
-     *
-     * <p>If the implementation has a non-void return type, the body will also include the {@code
-     * return} statement.
-     *
-     * @param simpleBindingExpression the expression to retrieve an instance of this binding without
-     *     the wrapping method.
-     */
-    abstract CodeBlock implementation(Supplier<CodeBlock> simpleBindingExpression);
-  }
-
-  /** Returns the {@code wrappedBindingExpression} directly. */
-  private static final class SimpleMethodImplementation extends BindingMethodImplementation {
-    @Override
-    CodeBlock implementation(Supplier<CodeBlock> simpleBindingExpression) {
-      return CodeBlock.of("return $L;", simpleBindingExpression.get());
-    }
-  }
-
-  /**
-   * Defines a method body for single checked caching of the given {@code wrappedBindingExpression}.
-   */
-  private final class SingleCheckedMethodImplementation extends BindingMethodImplementation {
-    private final Supplier<FieldSpec> field = Suppliers.memoize(this::createField);
-
-    @Override
-    CodeBlock implementation(Supplier<CodeBlock> simpleBindingExpression) {
-      String fieldExpression = field.get().name.equals("local") ? "this.local" : field.get().name;
-
-      CodeBlock.Builder builder = CodeBlock.builder()
-          .addStatement("Object local = $N", fieldExpression);
-
-      if (isNullable()) {
-        builder.beginControlFlow("if (local instanceof $T)", MemoizedSentinel.class);
-      } else {
-        builder.beginControlFlow("if (local == null)");
-      }
-
-      return builder
-          .addStatement("local = $L", simpleBindingExpression.get())
-          .addStatement("$N = ($T) local", fieldExpression, returnType())
-          .endControlFlow()
-          .addStatement("return ($T) local", returnType())
-          .build();
-    }
-
-    FieldSpec createField() {
-      String name =
-          componentImplementation.getUniqueFieldName(
-              request.isRequestKind(RequestKind.INSTANCE)
-                  ? KeyVariableNamer.name(binding.key())
-                  // TODO(ronshapiro): Use KeyVariableNamer directly so we don't need to use a
-                  // ResolvedBindings instance and construct a whole framework field just to get the
-                  // name
-                  : FrameworkField.forResolvedBindings(resolvedBindings, Optional.empty()).name());
-
-      FieldSpec.Builder builder = FieldSpec.builder(fieldType(), name, PRIVATE, VOLATILE);
-      if (isNullable()) {
-        builder.initializer("new $T()", MemoizedSentinel.class);
-      }
-
-      FieldSpec field = builder.build();
-      componentImplementation.addField(PRIVATE_METHOD_SCOPED_FIELD, field);
-      return field;
-    }
-
-    TypeName fieldType() {
-      if (isNullable()) {
-        // Nullable instances use `MemoizedSentinel` instead of `null` as the initialization value,
-        // so the field type must accept that and the return type
-        return TypeName.OBJECT;
-      }
-      TypeName returnType = TypeName.get(returnType());
-      return returnType.isPrimitive() ? returnType.box() : returnType;
-    }
-
-    private boolean isNullable() {
-      return request.isRequestKind(RequestKind.INSTANCE) && binding.isNullable();
-    }
-  }
-
-  /**
-   * Defines a method body for double checked caching of the given {@code wrappedBindingExpression}.
-   */
-  private final class DoubleCheckedMethodImplementation extends BindingMethodImplementation {
-    private final Supplier<String> fieldName = Suppliers.memoize(this::createField);
-
-    @Override
-    CodeBlock implementation(Supplier<CodeBlock> simpleBindingExpression) {
-      String fieldExpression = fieldName.get().equals("local") ? "this.local" : fieldName.get();
-      return CodeBlock.builder()
-          .addStatement("$T local = $L", TypeName.OBJECT, fieldExpression)
-          .beginControlFlow("if (local instanceof $T)", MemoizedSentinel.class)
-          .beginControlFlow("synchronized (local)")
-          .addStatement("local = $L", fieldExpression)
-          .beginControlFlow("if (local instanceof $T)", MemoizedSentinel.class)
-          .addStatement("local = $L", simpleBindingExpression.get())
-          .addStatement("$1L = $2T.reentrantCheck($1L, local)", fieldExpression, DoubleCheck.class)
-          .endControlFlow()
-          .endControlFlow()
-          .endControlFlow()
-          .addStatement("return ($T) local", returnType())
-          .build();
-    }
-
-    private String createField() {
-      String name =
-          componentImplementation.getUniqueFieldName(KeyVariableNamer.name(binding.key()));
-      componentImplementation.addField(
-          PRIVATE_METHOD_SCOPED_FIELD,
-          FieldSpec.builder(TypeName.OBJECT, name, PRIVATE, VOLATILE)
-              .initializer("new $T()", MemoizedSentinel.class)
-              .build());
-      return name;
-    }
-  }
-
-}
diff --git a/java/dagger/internal/codegen/MethodSignature.java b/java/dagger/internal/codegen/MethodSignature.java
deleted file mode 100644
index ef5c9c5..0000000
--- a/java/dagger/internal/codegen/MethodSignature.java
+++ /dev/null
@@ -1,55 +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 dagger.internal.codegen.DaggerStreams.toImmutableList;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.ImmutableList;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.List;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-@AutoValue
-abstract class MethodSignature {
-
-  abstract String name();
-
-  abstract ImmutableList<? extends Equivalence.Wrapper<? extends TypeMirror>> parameterTypes();
-
-  abstract ImmutableList<? extends Equivalence.Wrapper<? extends TypeMirror>> thrownTypes();
-
-  static MethodSignature forComponentMethod(
-      ComponentMethodDescriptor componentMethod, DeclaredType componentType, DaggerTypes types) {
-    ExecutableType methodType =
-        MoreTypes.asExecutable(types.asMemberOf(componentType, componentMethod.methodElement()));
-    return new AutoValue_MethodSignature(
-        componentMethod.methodElement().getSimpleName().toString(),
-        wrapInEquivalence(methodType.getParameterTypes()),
-        wrapInEquivalence(methodType.getThrownTypes()));
-  }
-
-  private static ImmutableList<? extends Equivalence.Wrapper<? extends TypeMirror>>
-      wrapInEquivalence(List<? extends TypeMirror> types) {
-    return types.stream().map(MoreTypes.equivalence()::wrap).collect(toImmutableList());
-  }
-}
diff --git a/java/dagger/internal/codegen/MethodSignatureFormatter.java b/java/dagger/internal/codegen/MethodSignatureFormatter.java
deleted file mode 100644
index 012d5b0..0000000
--- a/java/dagger/internal/codegen/MethodSignatureFormatter.java
+++ /dev/null
@@ -1,139 +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.checkState;
-import static dagger.internal.codegen.DiagnosticFormatting.stripCommonTypePrefixes;
-import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Formats the signature of an {@link ExecutableElement} suitable for use in error messages.
- */
-final class MethodSignatureFormatter extends Formatter<ExecutableElement> {
-  private final DaggerTypes types;
-
-  @Inject
-  MethodSignatureFormatter(DaggerTypes types) {
-    this.types = types;
-  }
-
-  /**
-   * A formatter that uses the type where the method is declared for the annotations and name of the
-   * method, but the method's resolved type as a member of {@code declaredType} for the key.
-   */
-  Formatter<ExecutableElement> typedFormatter(DeclaredType declaredType) {
-    return new Formatter<ExecutableElement>() {
-      @Override
-      public String format(ExecutableElement method) {
-        return MethodSignatureFormatter.this.format(
-            method,
-            MoreTypes.asExecutable(types.asMemberOf(declaredType, method)),
-            MoreElements.asType(method.getEnclosingElement()));
-      }
-    };
-  }
-
-  @Override public String format(ExecutableElement method) {
-    return format(method, Optional.empty());
-  }
-
-  /**
-   * Formats an ExecutableElement as if it were contained within the container, if the container is
-   * present.
-   */
-  public String format(ExecutableElement method, Optional<DeclaredType> container) {
-    TypeElement type = MoreElements.asType(method.getEnclosingElement());
-    ExecutableType executableType = MoreTypes.asExecutable(method.asType());
-    if (container.isPresent()) {
-      executableType = MoreTypes.asExecutable(types.asMemberOf(container.get(), method));
-      type = MoreElements.asType(container.get().asElement());
-    }
-    return format(method, executableType, type);
-  }
-
-  private String format(
-      ExecutableElement method, ExecutableType methodType, TypeElement declaringType) {
-    StringBuilder builder = new StringBuilder();
-    // TODO(cgruber): AnnotationMirror formatter.
-    List<? extends AnnotationMirror> annotations = method.getAnnotationMirrors();
-    if (!annotations.isEmpty()) {
-      Iterator<? extends AnnotationMirror> annotationIterator = annotations.iterator();
-      for (int i = 0; annotationIterator.hasNext(); i++) {
-        if (i > 0) {
-          builder.append(' ');
-        }
-        builder.append(formatAnnotation(annotationIterator.next()));
-      }
-      builder.append(' ');
-    }
-    if (method.getSimpleName().contentEquals("<init>")) {
-      builder.append(declaringType.getQualifiedName());
-    } else {
-      builder
-          .append(nameOfType(methodType.getReturnType()))
-          .append(' ')
-          .append(declaringType.getQualifiedName())
-          .append('.')
-          .append(method.getSimpleName());
-    }
-    builder.append('(');
-    checkState(method.getParameters().size() == methodType.getParameterTypes().size());
-    Iterator<? extends VariableElement> parameters = method.getParameters().iterator();
-    Iterator<? extends TypeMirror> parameterTypes = methodType.getParameterTypes().iterator();
-    for (int i = 0; parameters.hasNext(); i++) {
-      if (i > 0) {
-        builder.append(", ");
-      }
-      appendParameter(builder, parameters.next(), parameterTypes.next());
-    }
-    builder.append(')');
-    return builder.toString();
-  }
-
-  private static void appendParameter(StringBuilder builder, VariableElement parameter,
-      TypeMirror type) {
-    getQualifier(parameter)
-        .ifPresent(
-            qualifier -> {
-              builder.append(formatAnnotation(qualifier)).append(' ');
-            });
-    builder.append(nameOfType(type));
-  }
-
-  private static String nameOfType(TypeMirror type) {
-    return stripCommonTypePrefixes(type.toString());
-  }
-
-  private static String formatAnnotation(AnnotationMirror annotation) {
-    return stripCommonTypePrefixes(annotation.toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/MissingBindingExpression.java b/java/dagger/internal/codegen/MissingBindingExpression.java
deleted file mode 100644
index 610d052..0000000
--- a/java/dagger/internal/codegen/MissingBindingExpression.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A {@link ModifiableAbstractMethodBindingExpression} for a binding that is missing when generating
- * the abstract base class implementation of a subcomponent. The (unimplemented) method is added to
- * the {@link ComponentImplementation} when the dependency expression is requested. The method is
- * overridden when generating the implementation of an ancestor component.
- */
-final class MissingBindingExpression extends ModifiableAbstractMethodBindingExpression {
-  private final ComponentImplementation componentImplementation;
-  private final BindingRequest request;
-
-  MissingBindingExpression(
-      ComponentImplementation componentImplementation,
-      BindingRequest request,
-      Optional<ModifiableBindingMethod> matchingModifiableBindingMethod,
-      Optional<ComponentMethodDescriptor> matchingComponentMethod,
-      DaggerTypes types) {
-    super(
-        componentImplementation,
-        ModifiableBindingType.MISSING,
-        request,
-        matchingModifiableBindingMethod,
-        matchingComponentMethod,
-        types);
-    this.componentImplementation = componentImplementation;
-    this.request = request;
-  }
-
-  @Override
-  String chooseMethodName() {
-    return componentImplementation.getUniqueMethodName(request);
-  }
-
-  @Override
-  protected TypeMirror contributedType() {
-    return request.key().type();
-  }
-}
diff --git a/java/dagger/internal/codegen/MissingBindingValidator.java b/java/dagger/internal/codegen/MissingBindingValidator.java
deleted file mode 100644
index f39361d..0000000
--- a/java/dagger/internal/codegen/MissingBindingValidator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2018 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.Verify.verify;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.Keys.isValidImplicitProvisionKey;
-import static dagger.internal.codegen.Keys.isValidMembersInjectionKey;
-import static dagger.internal.codegen.RequestKinds.canBeSatisfiedByProductionBinding;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.MissingBinding;
-import dagger.model.BindingGraph.Node;
-import dagger.model.Key;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import javax.inject.Inject;
-import javax.lang.model.type.TypeKind;
-
-/** Reports errors for missing bindings. */
-final class MissingBindingValidator implements BindingGraphPlugin {
-
-  private final DaggerTypes types;
-  private final InjectBindingRegistry injectBindingRegistry;
-
-  @Inject
-  MissingBindingValidator(
-      DaggerTypes types, InjectBindingRegistry injectBindingRegistry) {
-    this.types = types;
-    this.injectBindingRegistry = injectBindingRegistry;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/MissingBinding";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph graph, DiagnosticReporter diagnosticReporter) {
-    // Don't report missing bindings when validating a full binding graph or a graph built from a
-    // subcomponent.
-    if (graph.isFullBindingGraph() || graph.rootComponentNode().isSubcomponent()) {
-      return;
-    }
-    graph
-        .missingBindings()
-        .forEach(missingBinding -> reportMissingBinding(missingBinding, graph, diagnosticReporter));
-  }
-
-  private void reportMissingBinding(
-      MissingBinding missingBinding, BindingGraph graph, DiagnosticReporter diagnosticReporter) {
-    diagnosticReporter.reportBinding(
-        ERROR, missingBinding, missingBindingErrorMessage(missingBinding, graph));
-  }
-
-  private String missingBindingErrorMessage(MissingBinding missingBinding, BindingGraph graph) {
-    Key key = missingBinding.key();
-    StringBuilder errorMessage = new StringBuilder();
-    // Wildcards should have already been checked by DependencyRequestValidator.
-    verify(!key.type().getKind().equals(TypeKind.WILDCARD), "unexpected wildcard request: %s", key);
-    // TODO(ronshapiro): replace "provided" with "satisfied"?
-    errorMessage.append(key).append(" cannot be provided without ");
-    if (isValidImplicitProvisionKey(key, types)) {
-      errorMessage.append("an @Inject constructor or ");
-    }
-    errorMessage.append("an @Provides-"); // TODO(dpb): s/an/a
-    if (allIncomingDependenciesCanUseProduction(missingBinding, graph)) {
-      errorMessage.append(" or @Produces-");
-    }
-    errorMessage.append("annotated method.");
-    if (isValidMembersInjectionKey(key) && typeHasInjectionSites(key)) {
-      errorMessage.append(
-          " This type supports members injection but cannot be implicitly provided.");
-    }
-    graph.bindings(key).stream()
-        .map(binding -> binding.componentPath().currentComponent())
-        .distinct()
-        .forEach(
-            component ->
-                errorMessage
-                    .append("\nA binding with matching key exists in component: ")
-                    .append(component.getQualifiedName()));
-    return errorMessage.toString();
-  }
-
-  private boolean allIncomingDependenciesCanUseProduction(
-      MissingBinding missingBinding, BindingGraph graph) {
-    return graph.network().inEdges(missingBinding).stream()
-        .flatMap(instancesOf(DependencyEdge.class))
-        .allMatch(edge -> dependencyCanBeProduction(edge, graph));
-  }
-
-  // TODO(ronshapiro): merge with
-  // ProvisionDependencyOnProduerBindingValidator.dependencyCanUseProduction
-  private boolean dependencyCanBeProduction(DependencyEdge edge, BindingGraph graph) {
-    Node source = graph.network().incidentNodes(edge).source();
-    if (source instanceof ComponentNode) {
-      return canBeSatisfiedByProductionBinding(edge.dependencyRequest().kind());
-    }
-    if (source instanceof dagger.model.Binding) {
-      return ((dagger.model.Binding) source).isProduction();
-    }
-    throw new IllegalArgumentException(
-        "expected a dagger.model.Binding or ComponentNode: " + source);
-  }
-
-  private boolean typeHasInjectionSites(Key key) {
-    return injectBindingRegistry
-        .getOrFindMembersInjectionBinding(key)
-        .map(binding -> !binding.injectionSites().isEmpty())
-        .orElse(false);
-  }
-}
diff --git a/java/dagger/internal/codegen/ModifiableAbstractMethodBindingExpression.java b/java/dagger/internal/codegen/ModifiableAbstractMethodBindingExpression.java
deleted file mode 100644
index 412acae..0000000
--- a/java/dagger/internal/codegen/ModifiableAbstractMethodBindingExpression.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2018 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 javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PROTECTED;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.Accessibility;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A {@link BindingExpression} that invokes a method that encapsulates a binding that cannot be
- * satisfied when generating the abstract base class implementation of a subcomponent. The
- * (unimplemented) method is added to the {@link ComponentImplementation} when the dependency
- * expression is requested. The method is overridden when generating the implementation of an
- * ancestor component.
- */
-abstract class ModifiableAbstractMethodBindingExpression extends BindingExpression {
-  private final ComponentImplementation componentImplementation;
-  private final ModifiableBindingType modifiableBindingType;
-  private final BindingRequest request;
-  private final Optional<ComponentMethodDescriptor> matchingComponentMethod;
-  private final DaggerTypes types;
-  private Optional<String> methodName;
-
-  ModifiableAbstractMethodBindingExpression(
-      ComponentImplementation componentImplementation,
-      ModifiableBindingType modifiableBindingType,
-      BindingRequest request,
-      Optional<ModifiableBindingMethod> matchingModifiableBindingMethod,
-      Optional<ComponentMethodDescriptor> matchingComponentMethod,
-      DaggerTypes types) {
-    this.componentImplementation = componentImplementation;
-    this.modifiableBindingType = modifiableBindingType;
-    this.request = request;
-    this.matchingComponentMethod = matchingComponentMethod;
-    this.types = types;
-    this.methodName =
-        initializeMethodName(matchingComponentMethod, matchingModifiableBindingMethod);
-  }
-
-  /**
-   * If this binding corresponds to an existing component method, or a known modifiable binding
-   * method, use them to initialize the method name, which is a signal to call the existing method
-   * rather than emit an abstract method.
-   */
-  private static Optional<String> initializeMethodName(
-      Optional<ComponentMethodDescriptor> matchingComponentMethod,
-      Optional<ModifiableBindingMethod> matchingModifiableBindingMethod) {
-    if (matchingComponentMethod.isPresent()) {
-      return Optional.of(matchingComponentMethod.get().methodElement().getSimpleName().toString());
-    }
-    if (matchingModifiableBindingMethod.isPresent()) {
-      return Optional.of(matchingModifiableBindingMethod.get().methodSpec().name);
-    }
-    return Optional.empty();
-  }
-
-  @Override
-  final Expression getDependencyExpression(ClassName requestingClass) {
-    addUnimplementedMethod();
-    return Expression.create(
-        returnType(),
-        componentImplementation.name().equals(requestingClass)
-            ? CodeBlock.of("$N()", methodName.get())
-            : CodeBlock.of("$T.this.$N()", componentImplementation.name(), methodName.get()));
-  }
-
-  private void addUnimplementedMethod() {
-    if (!methodName.isPresent()) {
-      // Only add the method once in case of repeated references to the missing binding.
-      methodName = Optional.of(chooseMethodName());
-      TypeMirror returnType = returnType();
-      componentImplementation.addModifiableBindingMethod(
-          modifiableBindingType,
-          request,
-          returnType,
-          MethodSpec.methodBuilder(methodName.get())
-              .addModifiers(PROTECTED, ABSTRACT)
-              .returns(TypeName.get(returnType))
-              .build(),
-          false /* finalized */);
-    }
-  }
-
-  /**
-   * The return type of this abstract method expression:
-   *
-   * <ul>
-   *   <li>If there's a {@code matchingComponentMethod}, use its return type.
-   *   <li>Otherwise, use the {@linkplain DaggerTypes#publiclyAccessibleType(TypeMirror) publicly
-   *       accessible type} of the request. We can't use the {@linkplain
-   *       Accessibility#isTypeAccessibleFrom(TypeMirror, String) type accessible from the current
-   *       implementation's package} because a subclass implementation may be in a different package
-   *       from which the request type is not accessible.
-   * </ul>
-   */
-  private TypeMirror returnType() {
-    if (matchingComponentMethod.isPresent()) {
-      return matchingComponentMethod.get().resolvedReturnType(types);
-    }
-
-    TypeMirror requestedType = request.requestedType(contributedType(), types);
-    return types.publiclyAccessibleType(requestedType);
-  }
-
-  /**
-   * The {@link ContributionBinding#contributedType() type contributed} by the binding of this
-   * expression. For missing bindings, this will be the key type.
-   */
-  protected abstract TypeMirror contributedType();
-
-  /** Returns a unique 'getter' method name for the current component. */
-  abstract String chooseMethodName();
-}
diff --git a/java/dagger/internal/codegen/ModifiableBindingExpressions.java b/java/dagger/internal/codegen/ModifiableBindingExpressions.java
deleted file mode 100644
index 76bcb8b..0000000
--- a/java/dagger/internal/codegen/ModifiableBindingExpressions.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright (C) 2016 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.checkState;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static java.util.stream.Collectors.toList;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PROTECTED;
-import static javax.lang.model.element.Modifier.PUBLIC;
-
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.MethodSpec;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.ComponentImplementation.MethodSpecKind;
-import dagger.internal.codegen.MethodBindingExpression.MethodImplementationStrategy;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import java.util.Optional;
-
-/**
- * A central repository of code expressions used to access modifiable bindings available to a
- * component. A binding is modifiable if it can be modified across implementations of a
- * subcomponent. This is only relevant for ahead-of-time subcomponents.
- */
-final class ModifiableBindingExpressions {
-  private final Optional<ModifiableBindingExpressions> parent;
-  private final ComponentBindingExpressions bindingExpressions;
-  private final BindingGraph graph;
-  private final ComponentImplementation componentImplementation;
-  private final CompilerOptions compilerOptions;
-  private final DaggerTypes types;
-
-  ModifiableBindingExpressions(
-      Optional<ModifiableBindingExpressions> parent,
-      ComponentBindingExpressions bindingExpressions,
-      BindingGraph graph,
-      ComponentImplementation componentImplementation,
-      CompilerOptions compilerOptions,
-      DaggerTypes types) {
-    this.parent = parent;
-    this.bindingExpressions = bindingExpressions;
-    this.graph = graph;
-    this.componentImplementation = componentImplementation;
-    this.compilerOptions = compilerOptions;
-    this.types = types;
-  }
-
-  /**
-   * Adds {@code method} to the component implementation. If the binding for the method is
-   * modifiable, also registers the relevant modifiable binding information.
-   */
-  void addPossiblyModifiableComponentMethod(
-      ComponentMethodDescriptor componentMethod, MethodSpec method) {
-    BindingRequest request = bindingRequest(componentMethod.dependencyRequest().get());
-    ModifiableBindingType modifiableBindingType = getModifiableBindingType(request);
-    if (modifiableBindingType.isModifiable()) {
-      componentImplementation.addModifiableComponentMethod(
-          modifiableBindingType,
-          request,
-          componentMethod.resolvedReturnType(types),
-          method,
-          newModifiableBindingWillBeFinalized(modifiableBindingType, request));
-    } else {
-      componentImplementation.addMethod(MethodSpecKind.COMPONENT_METHOD, method);
-    }
-  }
-
-  /**
-   * Returns the implementation of a modifiable binding method originally defined in a supertype
-   * implementation of this subcomponent. Returns {@link Optional#empty()} when the binding cannot
-   * or should not be modified by the current binding graph.
-   */
-  Optional<ModifiableBindingMethod> possiblyReimplementedMethod(
-      ModifiableBindingMethod modifiableBindingMethod) {
-    checkState(componentImplementation.superclassImplementation().isPresent());
-    BindingRequest request = modifiableBindingMethod.request();
-    ModifiableBindingType newModifiableBindingType = getModifiableBindingType(request);
-    ModifiableBindingType oldModifiableBindingType = modifiableBindingMethod.type();
-    boolean modifiableBindingTypeChanged =
-        !newModifiableBindingType.equals(oldModifiableBindingType);
-
-    ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-    // Don't reimplement modifiable bindings that were perceived to be provision bindings in a
-    // superclass implementation but are now production bindings.
-    if ((modifiableBindingTypeChanged
-            // Optional bindings don't need the same treatment since the only transition they can
-            // make is empty -> present. In that case, the Producer<Optional<T>> will be overridden
-            // and the absentOptionalProvider() will be a dangling reference that is never attempted
-            // to be overridden.
-            || newModifiableBindingType.equals(ModifiableBindingType.MULTIBINDING))
-        && resolvedBindings != null
-        && resolvedBindings.bindingType().equals(BindingType.PRODUCTION)
-        && !request.canBeSatisfiedByProductionBinding()) {
-      return oldModifiableBindingType.hasBaseClassImplementation()
-          ? Optional.empty()
-          : Optional.of(
-              reimplementedMethod(
-                  modifiableBindingMethod,
-                  newModifiableBindingType,
-                  new PrunedConcreteMethodBindingExpression(),
-                  componentImplementation.isAbstract()));
-    }
-
-    if (modifiableBindingTypeChanged
-        && !newModifiableBindingType.hasBaseClassImplementation()
-        && (oldModifiableBindingType.hasBaseClassImplementation()
-            || componentImplementation.isAbstract())) {
-      // We don't want to override one abstract method with another one. However, If the component
-      // is not abstract (such as a transition from GENERATED_INSTANCE -> MISSING), we must provide
-      // an implementation like normal.
-      return Optional.empty();
-    }
-
-    if (modifiableBindingTypeChanged
-        || shouldModifyImplementation(newModifiableBindingType, request)) {
-      boolean markMethodFinal =
-          knownModifiableBindingWillBeFinalized(modifiableBindingMethod)
-              // no need to mark the method final if the component implementation will be final
-              && componentImplementation.isAbstract();
-      return Optional.of(
-          reimplementedMethod(
-              modifiableBindingMethod,
-              newModifiableBindingType,
-              bindingExpressions.getBindingExpression(request),
-              markMethodFinal));
-    }
-    return Optional.empty();
-  }
-
-  /**
-   * Returns a new {@link ModifiableBindingMethod} that overrides {@code supertypeMethod} and is
-   * implemented with {@code bindingExpression}.
-   */
-  private ModifiableBindingMethod reimplementedMethod(
-      ModifiableBindingMethod supertypeMethod,
-      ModifiableBindingType newModifiableBindingType,
-      BindingExpression bindingExpression,
-      boolean markMethodFinal) {
-    MethodSpec baseMethod = supertypeMethod.methodSpec();
-    return supertypeMethod.reimplement(
-        newModifiableBindingType,
-        MethodSpec.methodBuilder(baseMethod.name)
-            .addModifiers(baseMethod.modifiers.contains(PUBLIC) ? PUBLIC : PROTECTED)
-            .addModifiers(markMethodFinal ? ImmutableSet.of(FINAL) : ImmutableSet.of())
-            .returns(baseMethod.returnType)
-            .addAnnotation(Override.class)
-            .addCode(
-                bindingExpression.getModifiableBindingMethodImplementation(
-                    supertypeMethod, componentImplementation, types))
-            .build(),
-        markMethodFinal);
-  }
-
-  /**
-   * Returns true if a modifiable binding method that was registered in a superclass implementation
-   * of this subcomponent should be marked as "finalized" if it is being overridden by this
-   * subcomponent implementation. "Finalized" means we should not attempt to modify the binding in
-   * any subcomponent subclass.
-   */
-  private boolean knownModifiableBindingWillBeFinalized(
-      ModifiableBindingMethod modifiableBindingMethod) {
-    ModifiableBindingType newModifiableBindingType =
-        getModifiableBindingType(modifiableBindingMethod.request());
-    if (!newModifiableBindingType.isModifiable()) {
-      // If a modifiable binding has become non-modifiable it is final by definition.
-      return true;
-    }
-    return modifiableBindingWillBeFinalized(
-        newModifiableBindingType,
-        shouldModifyImplementation(newModifiableBindingType, modifiableBindingMethod.request()));
-  }
-
-  /**
-   * Returns true if a newly discovered modifiable binding method, once it is defined in this
-   * subcomponent implementation, should be marked as "finalized", meaning we should not attempt to
-   * modify the binding in any subcomponent subclass.
-   */
-  private boolean newModifiableBindingWillBeFinalized(
-      ModifiableBindingType modifiableBindingType, BindingRequest request) {
-    return modifiableBindingWillBeFinalized(
-        modifiableBindingType, shouldModifyImplementation(modifiableBindingType, request));
-  }
-
-  /**
-   * Returns true if we shouldn't attempt to further modify a modifiable binding once we complete
-   * the implementation for the current subcomponent.
-   */
-  private boolean modifiableBindingWillBeFinalized(
-      ModifiableBindingType modifiableBindingType, boolean modifyingBinding) {
-    switch (modifiableBindingType) {
-      case MISSING:
-      case BINDS_METHOD_WITH_MISSING_DEPENDENCY:
-      case GENERATED_INSTANCE:
-      case OPTIONAL:
-      case INJECTION:
-        // Once we modify any of the above a single time, then they are finalized.
-        return modifyingBinding;
-      case MULTIBINDING:
-        return false;
-      default:
-        throw new IllegalStateException(
-            String.format(
-                "Building binding expression for unsupported ModifiableBindingType [%s].",
-                modifiableBindingType));
-    }
-  }
-
-  /**
-   * Creates a binding expression for a binding if it may be modified across implementations of a
-   * subcomponent.
-   */
-  Optional<BindingExpression> maybeCreateModifiableBindingExpression(BindingRequest request) {
-    ModifiableBindingType type = getModifiableBindingType(request);
-    if (!type.isModifiable()) {
-      return Optional.empty();
-    }
-    return Optional.of(createModifiableBindingExpression(type, request));
-  }
-
-  /** Creates a binding expression for a modifiable binding. */
-  private BindingExpression createModifiableBindingExpression(
-      ModifiableBindingType type, BindingRequest request) {
-    ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-    Optional<ModifiableBindingMethod> matchingModifiableBindingMethod =
-        componentImplementation.getModifiableBindingMethod(request);
-    Optional<ComponentMethodDescriptor> matchingComponentMethod =
-        graph.componentDescriptor().firstMatchingComponentMethod(request);
-    switch (type) {
-      case GENERATED_INSTANCE:
-        // If the subcomponent is abstract then we need to define an (un-implemented)
-        // DeferredModifiableBindingExpression.
-        if (componentImplementation.isAbstract()) {
-          return new DeferredModifiableBindingExpression(
-              componentImplementation,
-              type,
-              resolvedBindings.contributionBinding(),
-              request,
-              matchingModifiableBindingMethod,
-              matchingComponentMethod,
-              types);
-        }
-        // Otherwise return a concrete implementation.
-        return bindingExpressions.createBindingExpression(resolvedBindings, request);
-
-      case MISSING:
-        // If we need an expression for a missing binding and the current implementation is
-        // abstract, then we need an (un-implemented) MissingBindingExpression.
-        if (componentImplementation.isAbstract()) {
-          return new MissingBindingExpression(
-              componentImplementation,
-              request,
-              matchingModifiableBindingMethod,
-              matchingComponentMethod,
-              types);
-        }
-        // Otherwise we assume that it is valid to have a missing binding as it is part of a
-        // dependency chain that has been passively pruned.
-        // TODO(b/117833324): Identify pruned bindings when generating the subcomponent
-        // implementation in which the bindings are pruned. If we hold a reference to the binding
-        // graph used to generate a given implementation then we can compare a implementation's
-        // graph with its superclass implementation's graph to detect pruned dependency branches.
-        return new PrunedConcreteMethodBindingExpression();
-
-      case BINDS_METHOD_WITH_MISSING_DEPENDENCY:
-        checkState(componentImplementation.isAbstract());
-        return new DeferredModifiableBindingExpression(
-            componentImplementation,
-            type,
-            resolvedBindings.contributionBinding(),
-            request,
-            matchingModifiableBindingMethod,
-            matchingComponentMethod,
-            types);
-
-      case OPTIONAL:
-      case MULTIBINDING:
-      case INJECTION:
-        return bindingExpressions.wrapInMethod(
-            resolvedBindings,
-            request,
-            bindingExpressions.createBindingExpression(resolvedBindings, request));
-      default:
-        throw new IllegalStateException(
-            String.format(
-                "Building binding expression for unsupported ModifiableBindingType [%s].", type));
-    }
-  }
-
-  /**
-   * The reason why a binding may need to be modified across implementations of a subcomponent, if
-   * at all.
-   */
-  ModifiableBindingType getModifiableBindingType(BindingRequest request) {
-    if (!compilerOptions.aheadOfTimeSubcomponents()) {
-      return ModifiableBindingType.NONE;
-    }
-
-    // When generating a component the binding is not considered modifiable. Bindings are modifiable
-    // only across subcomponent implementations.
-    if (!componentImplementation.componentDescriptor().isSubcomponent()) {
-      return ModifiableBindingType.NONE;
-    }
-
-    if (request.requestKind().filter(RequestKinds::isDerivedFromProvider).isPresent()) {
-      return ModifiableBindingType.NONE;
-    }
-
-    if (resolvedInThisComponent(request)) {
-      ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-      if (resolvedBindings.contributionBindings().isEmpty()) {
-        // TODO(ronshapiro): Confirm whether a resolved binding must have a single contribution
-        // binding.
-        return ModifiableBindingType.NONE;
-      }
-
-      ContributionBinding binding = resolvedBindings.contributionBinding();
-      if (binding.requiresGeneratedInstance()) {
-        return ModifiableBindingType.GENERATED_INSTANCE;
-      }
-
-      if (binding.kind().equals(BindingKind.DELEGATE)
-          && graph
-              .contributionBindings()
-              .get(getOnlyElement(binding.dependencies()).key())
-              .isEmpty()) {
-        return ModifiableBindingType.BINDS_METHOD_WITH_MISSING_DEPENDENCY;
-      }
-
-      if (binding.kind().equals(BindingKind.OPTIONAL) && binding.dependencies().isEmpty()) {
-        // only empty optional bindings can be modified
-        return ModifiableBindingType.OPTIONAL;
-      }
-
-      if (binding.isSyntheticMultibinding()) {
-        return ModifiableBindingType.MULTIBINDING;
-      }
-
-      if (binding.kind().equals(BindingKind.INJECTION)) {
-        return ModifiableBindingType.INJECTION;
-      }
-    } else if (!resolvableBinding(request)) {
-      return ModifiableBindingType.MISSING;
-    }
-
-    return ModifiableBindingType.NONE;
-  }
-
-  /**
-   * Returns true if the current binding graph can, and should, modify a binding by overriding a
-   * modifiable binding method.
-   */
-  private boolean shouldModifyImplementation(
-      ModifiableBindingType modifiableBindingType, BindingRequest request) {
-    ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-    if (request.requestKind().isPresent()) {
-      switch (request.requestKind().get()) {
-        case FUTURE:
-          // Futures backed by production bindings are always requested by a Producer.get() call, so
-          // if the binding is modifiable, the producer will be wrapped in a modifiable method and
-          // the future can refer to that  method; even if the producer binding is modified,
-          // getModifiableProducer().get() will never need to be modified. Furthermore, because
-          // cancellation is treated by wrapped producers, and those producers point to the
-          // modifiable producer wrapper methods, we never need or want to change the access of
-          // these wrapped producers for entry methods
-          //
-          // Futures backed by provision bindings are inlined and contain no wrapping producer, so
-          // if the binding is modifiable and is resolved as a provision binding in a superclass
-          // but later resolved as a production binding, we can't take the same shortcut as before.
-          Optional<ComponentImplementation> superclassImplementation =
-              componentImplementation.superclassImplementation();
-          if (superclassImplementation.isPresent()) {
-            if (superclassImplementation.get().isDeserializedImplementation()) {
-              // TODO(b/117833324): consider serializing the binding type so that we don't need to
-              // branch here. Or, instead, consider removing this optimization entirely if there
-              // aren't that many FUTURE entry point methods to justify the extra code.
-              break;
-            } else {
-              return bindingTypeChanged(request, resolvedBindings);
-            }
-          }
-          return false;
-
-        case LAZY:
-        case PROVIDER_OF_LAZY:
-          // Lazy and ProviderOfLazy are always created from a Provider, and therefore this request
-          // never needs to be modifiable. It will refer (via DoubleCheck.lazy() or
-          // ProviderOfLazy.create()) to the modifiable method and not the framework instance.
-          return false;
-
-        case MEMBERS_INJECTION:
-        case PRODUCED:
-          // MEMBERS_INJECTION has a completely different code path for binding expressions, and
-          // PRODUCED requests are only requestable in @Produces methods, which are hidden from
-          // generated components inside Producer factories
-          throw new AssertionError(request);
-
-        case INSTANCE:
-        case PROVIDER:
-        case PRODUCER:
-          // These may be modifiable, so run through the regular logic. They're spelled out
-          // explicitly so that ErrorProne will detect if a new enum value is created and missing
-          // from this list.
-          break;
-      }
-    }
-
-    switch (modifiableBindingType) {
-      case GENERATED_INSTANCE:
-        return !componentImplementation.isAbstract();
-
-      case MISSING:
-        // TODO(b/117833324): investigate beder@'s comment about having intermediate component
-        // ancestors satisfy missing bindings of their children with their own missing binding
-        // methods so that we can minimize the cases where we need to reach into doubly-nested
-        // descendant component implementations.
-
-        // Implement a missing binding if it is resolvable, or if we're generating a concrete
-        // subcomponent implementation. If a binding is still missing when the subcomponent
-        // implementation is concrete then it is assumed to be part of a dependency that would have
-        // been passively pruned when implementing the full component hierarchy.
-        return resolvableBinding(request) || !componentImplementation.isAbstract();
-
-      case BINDS_METHOD_WITH_MISSING_DEPENDENCY:
-        DependencyRequest dependency =
-            getOnlyElement(resolvedBindings.contributionBinding().dependencies());
-        return !graph.contributionBindings().get(dependency.key()).isEmpty();
-
-      case OPTIONAL:
-        // Only override optional binding methods if we have a non-empty binding.
-        return !resolvedBindings.contributionBinding().dependencies().isEmpty();
-
-      case MULTIBINDING:
-        // Only modify a multibinding if there are new contributions.
-        return !componentImplementation
-            .superclassContributionsMade(request)
-            .containsAll(
-                resolvedBindings.contributionBinding().dependencies().stream()
-                    .map(DependencyRequest::key)
-                    .collect(toList()));
-
-      case INJECTION:
-        return !resolvedBindings.contributionBinding().kind().equals(BindingKind.INJECTION);
-
-      default:
-        throw new IllegalStateException(
-            String.format(
-                "Overriding modifiable binding method with unsupported ModifiableBindingType [%s].",
-                modifiableBindingType));
-    }
-  }
-
-  /**
-   * Returns {@code true} if the {@link BindingType} for {@code request} is not the same in this
-   * implementation and it's superclass implementation.
-   */
-  private boolean bindingTypeChanged(BindingRequest request, ResolvedBindings resolvedBindings) {
-    BindingGraph superclassGraph =
-        componentImplementation.superclassImplementation().get().graph();
-    ResolvedBindings superclassBindings = superclassGraph.resolvedBindings(request);
-    return superclassBindings != null
-        && resolvedBindings != null
-        && !superclassBindings.bindingType().equals(resolvedBindings.bindingType());
-  }
-
-  /**
-   * Returns true if the binding can be resolved by the graph for this component or any parent
-   * component.
-   */
-  private boolean resolvableBinding(BindingRequest request) {
-    for (ModifiableBindingExpressions expressions = this;
-        expressions != null;
-        expressions = expressions.parent.orElse(null)) {
-      if (expressions.resolvedInThisComponent(request)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /** Returns true if the binding can be resolved by the graph for this component. */
-  private boolean resolvedInThisComponent(BindingRequest request) {
-    ResolvedBindings resolvedBindings = graph.resolvedBindings(request);
-    return resolvedBindings != null
-        && !resolvedBindings.bindingsOwnedBy(graph.componentDescriptor()).isEmpty();
-  }
-
-  /**
-   * Wraps a modifiable binding expression in a method that can be overridden in a subclass
-   * implementation.
-   */
-  BindingExpression wrapInModifiableMethodBindingExpression(
-      BindingRequest request,
-      ResolvedBindings resolvedBindings,
-      MethodImplementationStrategy methodImplementationStrategy,
-      BindingExpression wrappedBindingExpression) {
-    ModifiableBindingType modifiableBindingType = getModifiableBindingType(request);
-    checkState(modifiableBindingType.isModifiable());
-    return new ModifiableConcreteMethodBindingExpression(
-        request,
-        resolvedBindings,
-        methodImplementationStrategy,
-        wrappedBindingExpression,
-        modifiableBindingType,
-        componentImplementation,
-        newModifiableBindingWillBeFinalized(modifiableBindingType, request),
-        types);
-  }
-}
diff --git a/java/dagger/internal/codegen/ModifiableBindingMethods.java b/java/dagger/internal/codegen/ModifiableBindingMethods.java
deleted file mode 100644
index ead708d..0000000
--- a/java/dagger/internal/codegen/ModifiableBindingMethods.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2018 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.Verify.verify;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.squareup.javapoet.MethodSpec;
-import java.util.Map;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A registry for those methods which each wrap a binding whose definition may be modified across
- * each class in the class hierarchy implementing a subcomponent. Subcomponent implementations are
- * spread across a class hierarchy when generating ahead-of-time subcomponents. There is one
- * subcomponent implementation class for each of the subcomponent's ancestor components. An instance
- * of {@link ModifiableBindingMethod} is associated with a single class in this hierarchy. For a
- * given subcomponent implementation class we can use the {@link ModifiableBindingMethod}s of its
- * superclasses to know what binding methods to attempt to modify.
- */
-final class ModifiableBindingMethods {
-  private final Map<BindingRequest, ModifiableBindingMethod> methods = Maps.newLinkedHashMap();
-
-  /** Registers a new method encapsulating a modifiable binding. */
-  void addModifiableMethod(
-      ModifiableBindingType type,
-      BindingRequest request,
-      TypeMirror returnType,
-      MethodSpec method,
-      boolean finalized) {
-    // It's ok for the type to not be modifiable, since it could be overriding a previously
-    // modifiable method (such as with addReimplementedMethod).
-    addMethod(ModifiableBindingMethod.create(type, request, returnType, method, finalized));
-  }
-
-  /** Registers a reimplemented modifiable method. */
-  void addReimplementedMethod(ModifiableBindingMethod method) {
-    addMethod(method);
-  }
-
-  private void addMethod(ModifiableBindingMethod method) {
-    ModifiableBindingMethod previousMethod = methods.put(method.request(), method);
-    verify(
-        previousMethod == null,
-        "registering %s but %s is already registered for the same binding request",
-        method,
-        previousMethod);
-  }
-
-  /** Returns all {@link ModifiableBindingMethod}s that have not been marked as finalized. */
-  ImmutableMap<BindingRequest, ModifiableBindingMethod> getNonFinalizedMethods() {
-    return ImmutableMap.copyOf(Maps.filterValues(methods, m -> !m.finalized()));
-  }
-
-  /** Returns the {@link ModifiableBindingMethod} for the given binding if present. */
-  Optional<ModifiableBindingMethod> getMethod(BindingRequest request) {
-    return Optional.ofNullable(methods.get(request));
-  }
-
-  /** Returns all of the {@link ModifiableBindingMethod}s. */
-  ImmutableList<ModifiableBindingMethod> allMethods() {
-    return ImmutableList.copyOf(methods.values());
-  }
-
-  /** Whether a given binding has been marked as finalized. */
-  // TODO(ronshapiro): possibly rename this to something that indicates that the BindingRequest for
-  // `method` has been finalized in *this* component implementation?
-  boolean finalized(ModifiableBindingMethod method) {
-    ModifiableBindingMethod storedMethod = methods.get(method.request());
-    return storedMethod != null && storedMethod.finalized();
-  }
-
-  @AutoValue
-  abstract static class ModifiableBindingMethod {
-    private static ModifiableBindingMethod create(
-        ModifiableBindingType type,
-        BindingRequest request,
-        TypeMirror returnType,
-        MethodSpec methodSpec,
-        boolean finalized) {
-      return new AutoValue_ModifiableBindingMethods_ModifiableBindingMethod(
-          type, request, MoreTypes.equivalence().wrap(returnType), methodSpec, finalized);
-    }
-
-    /** Creates a {@ModifiableBindingMethod} that reimplements the current method. */
-    ModifiableBindingMethod reimplement(
-        ModifiableBindingType newModifiableBindingType,
-        MethodSpec newImplementation,
-        boolean finalized) {
-      return new AutoValue_ModifiableBindingMethods_ModifiableBindingMethod(
-          newModifiableBindingType, request(), returnTypeWrapper(), newImplementation, finalized);
-    }
-
-    abstract ModifiableBindingType type();
-
-    abstract BindingRequest request();
-
-    final TypeMirror returnType() {
-      return returnTypeWrapper().get();
-    }
-
-    abstract Equivalence.Wrapper<TypeMirror> returnTypeWrapper();
-
-    abstract MethodSpec methodSpec();
-
-    abstract boolean finalized();
-
-    /** Whether a {@link ModifiableBindingMethod} is for the same binding request. */
-    boolean fulfillsSameRequestAs(ModifiableBindingMethod other) {
-      return request().equals(other.request());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ModifiableBindingType.java b/java/dagger/internal/codegen/ModifiableBindingType.java
deleted file mode 100644
index 7e43ec1..0000000
--- a/java/dagger/internal/codegen/ModifiableBindingType.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.collect.ImmutableSet;
-
-/**
- * A label for a binding indicating whether, and how, it may be redefined across implementations of
- * a subcomponent.
- *
- * <p>A subcomponent has multiple implementations only when generating ahead-of-time subcomponents.
- * Specifically, each subcomponent type in a component hierarchy is implemented as an abstract
- * class, and descendent components are implemented as abstract inner classes. A consequence of this
- * is that a given subcomponent has an implementation for each ancestor component. Each
- * implementation represents a different sub-binding-graph of the full subcomponent. A binding is
- * modifiable if it's definition may change depending on the characteristics of its ancestor
- * components.
- */
-enum ModifiableBindingType {
-  /** A binding that is not modifiable */
-  NONE,
-
-  /**
-   * A binding that is missing when generating the abstract base class implementation of a
-   * subcomponent.
-   */
-  MISSING,
-
-  /**
-   * A binding that requires an instance of a generated type. These binding are modifiable in the
-   * sense that they are encapsulated in a method when they are first required, possibly in an
-   * abstract implementation of a subcomponent, where, in general, no concrete instances of
-   * generated types are available, and the method is satisfied in a final concrete implementation.
-   */
-  GENERATED_INSTANCE,
-
-  /**
-   * Multibindings may have contributions come from any ancestor component. Therefore, each
-   * implementation of a subcomponent may have newly available contributions, and so the binding
-   * method is reimplemented with each subcomponent implementation.
-   */
-  MULTIBINDING,
-
-  /**
-   * A Optional binding that may be empty when looking at a partial binding graph, but bound to a
-   * value when considering the complete binding graph, thus modifiable across subcomponent
-   * implementations.
-   */
-  OPTIONAL,
-
-  /**
-   * If a binding is defined according to an {@code @Inject} annotated constructor on the object it
-   * is valid for that binding to be redefined a single time by an {@code @Provides} annotated
-   * module method. It is possible that the {@code @Provides} binding isn't available in a partial
-   * binding graph, but becomes available when considering a more complete binding graph, therefore
-   * such bindings are modifiable across subcomponent implementations.
-   */
-  INJECTION,
-
-  /**
-   * A {@link dagger.Binds} method whose dependency is {@link #MISSING}.
-   *
-   * <p>There's not much to do for @Binds bindings if the dependency is missing - at best, if the
-   * dependency is a weaker scope/unscoped, we save only a few lines that implement the scoping. But
-   * it's also possible, if the dependency is the same or stronger scope, that no extra code is
-   * necessary, in which case we'd be overriding a method that just returns another.
-   */
-  BINDS_METHOD_WITH_MISSING_DEPENDENCY,
-  ;
-
-  private static final ImmutableSet<ModifiableBindingType> TYPES_WITH_BASE_CLASS_IMPLEMENTATIONS =
-      ImmutableSet.of(NONE, INJECTION, MULTIBINDING, OPTIONAL);
-
-  boolean isModifiable() {
-    return !equals(NONE);
-  }
-
-  /**
-   * Returns true if the method encapsulating the modifiable binding should have a concrete
-   * implementation in the abstract base class for a subcomponent.
-   */
-  boolean hasBaseClassImplementation() {
-    return TYPES_WITH_BASE_CLASS_IMPLEMENTATIONS.contains(this);
-  }
-}
diff --git a/java/dagger/internal/codegen/ModifiableConcreteMethodBindingExpression.java b/java/dagger/internal/codegen/ModifiableConcreteMethodBindingExpression.java
deleted file mode 100644
index 907466b..0000000
--- a/java/dagger/internal/codegen/ModifiableConcreteMethodBindingExpression.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.PROTECTED;
-
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.util.Optional;
-
-/**
- * A binding expression that wraps a modifiable binding expression in a public, no-arg method.
- *
- * <p>Dependents of this binding expression will just call the modifiable binding method.
- */
-final class ModifiableConcreteMethodBindingExpression extends MethodBindingExpression {
-
-  private final BindingRequest request;
-  private final ModifiableBindingType modifiableBindingType;
-  private final ComponentImplementation componentImplementation;
-  private final boolean bindingCannotBeModified;
-  private Optional<String> methodName = Optional.empty();
-
-  ModifiableConcreteMethodBindingExpression(
-      BindingRequest request,
-      ResolvedBindings resolvedBindings,
-      MethodImplementationStrategy methodImplementationStrategy,
-      BindingExpression wrappedBindingExpression,
-      ModifiableBindingType modifiableBindingType,
-      ComponentImplementation componentImplementation,
-      boolean bindingCannotBeModified,
-      DaggerTypes types) {
-    super(
-        request,
-        resolvedBindings,
-        methodImplementationStrategy,
-        wrappedBindingExpression,
-        componentImplementation,
-        types);
-    this.request = checkNotNull(request);
-    this.modifiableBindingType = checkNotNull(modifiableBindingType);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.bindingCannotBeModified = bindingCannotBeModified;
-  }
-
-  @Override
-  protected void addMethod() {
-    if (methodName.isPresent()) {
-      return;
-    }
-
-    if (supertypeModifiableBindingMethod().isPresent()) {
-      methodName = supertypeModifiableBindingMethod().map(method -> method.methodSpec().name);
-      return;
-    }
-
-    // Add the modifiable binding method to the component if we haven't already.
-    methodName = Optional.of(componentImplementation.getUniqueMethodName(request));
-    componentImplementation.addModifiableBindingMethod(
-        modifiableBindingType,
-        request,
-        returnType(),
-        methodBuilder(methodName.get())
-            .addModifiers(bindingCannotBeModified ? PRIVATE : PROTECTED)
-            .returns(TypeName.get(returnType()))
-            .addCode(methodBody())
-            .build(),
-        bindingCannotBeModified);
-  }
-
-  @Override
-  protected String methodName() {
-    checkState(methodName.isPresent(), "addMethod() must be called before methodName().");
-    return methodName.get();
-  }
-
-  @Override
-  protected boolean isModifiableImplementationMethod() {
-    return true;
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleAnnotation.java b/java/dagger/internal/codegen/ModuleAnnotation.java
deleted file mode 100644
index 27dd071..0000000
--- a/java/dagger/internal/codegen/ModuleAnnotation.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2019 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.auto.common.AnnotationMirrors.getAnnotationValue;
-import static com.google.auto.common.MoreTypes.asTypeElement;
-import static com.google.common.base.Preconditions.checkArgument;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.MoreAnnotationValues.asAnnotationValues;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnyAnnotation;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.TypeElement;
-
-/** A {@code @Module} or {@code @ProducerModule} annotation. */
-@AutoValue
-abstract class ModuleAnnotation {
-  private static final ImmutableSet<Class<? extends Annotation>> MODULE_ANNOTATIONS =
-      ImmutableSet.of(Module.class, ProducerModule.class);
-
-  /** The annotation itself. */
-  // This does not use AnnotationMirrors.equivalence() because we want the actual annotation
-  // instance.
-  abstract AnnotationMirror annotation();
-
-  /** The type of the annotation. */
-  @Memoized
-  Class<?> annotationClass() {
-    try {
-      return Class.forName(
-          asTypeElement(annotation().getAnnotationType()).getQualifiedName().toString());
-    } catch (ClassNotFoundException e) {
-      AssertionError assertionError = new AssertionError();
-      assertionError.initCause(e);
-      throw assertionError;
-    }
-  }
-
-  /**
-   * The types specified in the {@code includes} attribute.
-   *
-   * @throws IllegalArgumentException if any of the values are error types
-   */
-  @Memoized
-  ImmutableList<TypeElement> includes() {
-    return includesAsAnnotationValues().stream()
-        .map(MoreAnnotationValues::asType)
-        .map(MoreTypes::asTypeElement)
-        .collect(toImmutableList());
-  }
-
-  /** The values specified in the {@code includes} attribute. */
-  @Memoized
-  ImmutableList<AnnotationValue> includesAsAnnotationValues() {
-    return asAnnotationValues(getAnnotationValue(annotation(), "includes"));
-  }
-
-  /**
-   * The types specified in the {@code subcomponents} attribute.
-   *
-   * @throws IllegalArgumentException if any of the values are error types
-   */
-  @Memoized
-  ImmutableList<TypeElement> subcomponents() {
-    return subcomponentsAsAnnotationValues().stream()
-        .map(MoreAnnotationValues::asType)
-        .map(MoreTypes::asTypeElement)
-        .collect(toImmutableList());
-  }
-
-  /** The values specified in the {@code subcomponents} attribute. */
-  @Memoized
-  ImmutableList<AnnotationValue> subcomponentsAsAnnotationValues() {
-    return asAnnotationValues(getAnnotationValue(annotation(), "subcomponents"));
-  }
-
-  /** Returns {@code true} if the argument is a {@code @Module} or {@code @ProducerModule}. */
-  static boolean isModuleAnnotation(AnnotationMirror annotation) {
-    return MODULE_ANNOTATIONS.stream()
-        .map(Class::getCanonicalName)
-        .anyMatch(asTypeElement(annotation.getAnnotationType()).getQualifiedName()::contentEquals);
-  }
-
-  /** The module annotation types. */
-  static ImmutableSet<Class<? extends Annotation>> moduleAnnotations() {
-    return MODULE_ANNOTATIONS;
-  }
-
-  /**
-   * Creates an object that represents a {@code @Module} or {@code @ProducerModule}.
-   *
-   * @throws IllegalArgumentException if {@link #isModuleAnnotation(AnnotationMirror)} returns
-   *     {@code false}
-   */
-  static ModuleAnnotation moduleAnnotation(AnnotationMirror annotation) {
-    checkArgument(
-        isModuleAnnotation(annotation),
-        "%s is not a Module or ProducerModule annotation",
-        annotation);
-    return new AutoValue_ModuleAnnotation(annotation);
-  }
-
-  /**
-   * Returns an object representing the {@code @Module} or {@code @ProducerModule} annotation if one
-   * annotates {@code typeElement}.
-   */
-  static Optional<ModuleAnnotation> moduleAnnotation(TypeElement typeElement) {
-    return getAnyAnnotation(typeElement, Module.class, ProducerModule.class)
-        .map(ModuleAnnotation::moduleAnnotation);
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleConstructorProxyGenerator.java b/java/dagger/internal/codegen/ModuleConstructorProxyGenerator.java
deleted file mode 100644
index 5f0d687..0000000
--- a/java/dagger/internal/codegen/ModuleConstructorProxyGenerator.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2018 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.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.ModuleKind.checkIsModule;
-import static dagger.internal.codegen.ModuleProxies.nonPublicNullaryConstructor;
-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;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Generates a {@code public static} method that calls {@code new SomeModule()} for modules that
- * don't have {@linkplain ModuleProxies#nonPublicNullaryConstructor(TypeElement,
- * DaggerElements) publicly accessible constructors}.
- */
-// TODO(dpb): See if this can become a SourceFileGenerator<ModuleDescriptor> instead. Doing so may
-// cause ModuleProcessingStep to defer elements multiple times.
-final class ModuleConstructorProxyGenerator extends SourceFileGenerator<TypeElement> {
-  private final DaggerElements elements;
-
-  @Inject
-  ModuleConstructorProxyGenerator(
-      Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-    this.elements = elements;
-  }
-
-  @Override
-  ClassName nameGeneratedType(TypeElement moduleElement) {
-    return ModuleProxies.constructorProxyTypeName(moduleElement);
-  }
-
-  @Override
-  Element originatingElement(TypeElement moduleElement) {
-    return moduleElement;
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, TypeElement moduleElement) {
-    checkIsModule(moduleElement);
-    return nonPublicNullaryConstructor(moduleElement, elements).isPresent()
-        ? Optional.of(buildProxy(generatedTypeName, moduleElement))
-        : Optional.empty();
-  }
-
-  private TypeSpec.Builder buildProxy(ClassName generatedTypeName, TypeElement moduleElement) {
-    return classBuilder(generatedTypeName)
-        .addModifiers(PUBLIC, FINAL)
-        .addMethod(constructorBuilder().addModifiers(PRIVATE).build())
-        .addMethod(
-            methodBuilder("newInstance")
-                .addModifiers(PUBLIC, STATIC)
-                .returns(ClassName.get(moduleElement))
-                .addStatement("return new $T()", moduleElement)
-                .build());
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleDescriptor.java b/java/dagger/internal/codegen/ModuleDescriptor.java
deleted file mode 100644
index ac7a4b7..0000000
--- a/java/dagger/internal/codegen/ModuleDescriptor.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreElements.getPackage;
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.Verify.verify;
-import static com.google.common.collect.Iterables.transform;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-import static dagger.internal.codegen.SourceFiles.classFileName;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnnotationPresent;
-import static javax.lang.model.type.TypeKind.DECLARED;
-import static javax.lang.model.type.TypeKind.NONE;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.graph.Traverser;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.squareup.javapoet.ClassName;
-import dagger.Binds;
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.Key;
-import dagger.multibindings.Multibinds;
-import dagger.producers.Produces;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-
-@AutoValue
-abstract class ModuleDescriptor {
-
-  abstract TypeElement moduleElement();
-
-  abstract ImmutableSet<TypeElement> includedModules();
-
-  abstract ImmutableSet<ContributionBinding> bindings();
-
-  /** The multibinding declarations contained in this module. */
-  abstract ImmutableSet<MultibindingDeclaration> multibindingDeclarations();
-
-  /** The {@link Module#subcomponents() subcomponent declarations} contained in this module. */
-  abstract ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations();
-
-  /** The {@link Binds} method declarations that define delegate bindings. */
-  abstract ImmutableSet<DelegateDeclaration> delegateDeclarations();
-
-  /** The {@link BindsOptionalOf} method declarations that define optional bindings. */
-  abstract ImmutableSet<OptionalBindingDeclaration> optionalDeclarations();
-
-  /** The kind of the module. */
-  abstract ModuleKind kind();
-
-  /** Returns all of the bindings declared in this module. */
-  @Memoized
-  ImmutableSet<BindingDeclaration> allBindingDeclarations() {
-    return ImmutableSet.<BindingDeclaration>builder()
-        .addAll(bindings())
-        .addAll(delegateDeclarations())
-        .addAll(multibindingDeclarations())
-        .addAll(optionalDeclarations())
-        .addAll(subcomponentDeclarations())
-        .build();
-  }
-
-  /** Returns the keys of all bindings declared by this module. */
-  ImmutableSet<Key> allBindingKeys() {
-    return allBindingDeclarations().stream().map(BindingDeclaration::key).collect(toImmutableSet());
-  }
-
-  @Singleton
-  static final class Factory implements ClearableCache {
-    private final DaggerElements elements;
-    private final BindingFactory bindingFactory;
-    private final MultibindingDeclaration.Factory multibindingDeclarationFactory;
-    private final DelegateDeclaration.Factory bindingDelegateDeclarationFactory;
-    private final SubcomponentDeclaration.Factory subcomponentDeclarationFactory;
-    private final OptionalBindingDeclaration.Factory optionalBindingDeclarationFactory;
-    private final Map<TypeElement, ModuleDescriptor> cache = new HashMap<>();
-
-    @Inject
-    Factory(
-        DaggerElements elements,
-        BindingFactory bindingFactory,
-        MultibindingDeclaration.Factory multibindingDeclarationFactory,
-        DelegateDeclaration.Factory bindingDelegateDeclarationFactory,
-        SubcomponentDeclaration.Factory subcomponentDeclarationFactory,
-        OptionalBindingDeclaration.Factory optionalBindingDeclarationFactory) {
-      this.elements = elements;
-      this.bindingFactory = bindingFactory;
-      this.multibindingDeclarationFactory = multibindingDeclarationFactory;
-      this.bindingDelegateDeclarationFactory = bindingDelegateDeclarationFactory;
-      this.subcomponentDeclarationFactory = subcomponentDeclarationFactory;
-      this.optionalBindingDeclarationFactory = optionalBindingDeclarationFactory;
-    }
-
-    ModuleDescriptor create(TypeElement moduleElement) {
-      return reentrantComputeIfAbsent(cache, moduleElement, this::createUncached);
-    }
-
-    ModuleDescriptor createUncached(TypeElement moduleElement) {
-      ImmutableSet.Builder<ContributionBinding> bindings = ImmutableSet.builder();
-      ImmutableSet.Builder<DelegateDeclaration> delegates = ImmutableSet.builder();
-      ImmutableSet.Builder<MultibindingDeclaration> multibindingDeclarations =
-          ImmutableSet.builder();
-      ImmutableSet.Builder<OptionalBindingDeclaration> optionalDeclarations =
-          ImmutableSet.builder();
-
-      for (ExecutableElement moduleMethod : methodsIn(elements.getAllMembers(moduleElement))) {
-        if (isAnnotationPresent(moduleMethod, Provides.class)) {
-          bindings.add(bindingFactory.providesMethodBinding(moduleMethod, moduleElement));
-        }
-        if (isAnnotationPresent(moduleMethod, Produces.class)) {
-          bindings.add(bindingFactory.producesMethodBinding(moduleMethod, moduleElement));
-        }
-        if (isAnnotationPresent(moduleMethod, Binds.class)) {
-          delegates.add(bindingDelegateDeclarationFactory.create(moduleMethod, moduleElement));
-        }
-        if (isAnnotationPresent(moduleMethod, Multibinds.class)) {
-          multibindingDeclarations.add(
-              multibindingDeclarationFactory.forMultibindsMethod(moduleMethod, moduleElement));
-        }
-        if (isAnnotationPresent(moduleMethod, BindsOptionalOf.class)) {
-          optionalDeclarations.add(
-              optionalBindingDeclarationFactory.forMethod(moduleMethod, moduleElement));
-        }
-      }
-
-      return new AutoValue_ModuleDescriptor(
-          moduleElement,
-          ImmutableSet.copyOf(collectIncludedModules(new LinkedHashSet<>(), moduleElement)),
-          bindings.build(),
-          multibindingDeclarations.build(),
-          subcomponentDeclarationFactory.forModule(moduleElement),
-          delegates.build(),
-          optionalDeclarations.build(),
-          ModuleKind.forAnnotatedElement(moduleElement).get());
-    }
-
-    /** Returns all the modules transitively included by given modules, including the arguments. */
-    ImmutableSet<ModuleDescriptor> transitiveModules(Iterable<TypeElement> modules) {
-      return ImmutableSet.copyOf(
-          Traverser.forGraph(
-                  (ModuleDescriptor module) -> transform(module.includedModules(), this::create))
-              .depthFirstPreOrder(transform(modules, this::create)));
-    }
-
-    @CanIgnoreReturnValue
-    private Set<TypeElement> collectIncludedModules(
-        Set<TypeElement> includedModules, TypeElement moduleElement) {
-      TypeMirror superclass = moduleElement.getSuperclass();
-      if (!superclass.getKind().equals(NONE)) {
-        verify(superclass.getKind().equals(DECLARED));
-        TypeElement superclassElement = MoreTypes.asTypeElement(superclass);
-        if (!superclassElement.getQualifiedName().contentEquals(Object.class.getCanonicalName())) {
-          collectIncludedModules(includedModules, superclassElement);
-        }
-      }
-      moduleAnnotation(moduleElement)
-          .ifPresent(
-              moduleAnnotation -> {
-                includedModules.addAll(moduleAnnotation.includes());
-                includedModules.addAll(implicitlyIncludedModules(moduleElement));
-              });
-      return includedModules;
-    }
-
-    // @ContributesAndroidInjector generates a module that is implicitly included in the enclosing
-    // module
-    private ImmutableSet<TypeElement> implicitlyIncludedModules(TypeElement moduleElement) {
-      TypeElement contributesAndroidInjector =
-          elements.getTypeElement("dagger.android.ContributesAndroidInjector");
-      if (contributesAndroidInjector == null) {
-        return ImmutableSet.of();
-      }
-      return methodsIn(moduleElement.getEnclosedElements()).stream()
-          .filter(method -> isAnnotationPresent(method, contributesAndroidInjector.asType()))
-          .map(method -> elements.checkTypePresent(implicitlyIncludedModuleName(method)))
-          .collect(toImmutableSet());
-    }
-
-    private String implicitlyIncludedModuleName(ExecutableElement method) {
-      return getPackage(method).getQualifiedName()
-          + "."
-          + classFileName(ClassName.get(MoreElements.asType(method.getEnclosingElement())))
-          + "_"
-          + LOWER_CAMEL.to(UPPER_CAMEL, method.getSimpleName().toString());
-    }
-
-    @Override
-    public void clearCache() {
-      cache.clear();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleGenerator.java b/java/dagger/internal/codegen/ModuleGenerator.java
deleted file mode 100644
index 161b47b..0000000
--- a/java/dagger/internal/codegen/ModuleGenerator.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/** Qualifier for a {@link SourceFileGenerator} for modules. */
-@Qualifier
-@Retention(RUNTIME)
-@interface ModuleGenerator {}
diff --git a/java/dagger/internal/codegen/ModuleKind.java b/java/dagger/internal/codegen/ModuleKind.java
deleted file mode 100644
index c93d8ce..0000000
--- a/java/dagger/internal/codegen/ModuleKind.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnnotationMirror;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.lang.annotation.Annotation;
-import java.util.EnumSet;
-import java.util.Optional;
-import java.util.Set;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.TypeElement;
-
-/** Enumeration of the kinds of modules. */
-enum ModuleKind {
-  /** {@code @Module} */
-  MODULE(Module.class),
-
-  /** {@code @ProducerModule} */
-  PRODUCER_MODULE(ProducerModule.class);
-
-  /** Returns the annotations for modules of the given kinds. */
-  static ImmutableSet<Class<? extends Annotation>> annotationsFor(Set<ModuleKind> kinds) {
-    return kinds.stream().map(ModuleKind::annotation).collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the kind of an annotated element if it is annotated with one of the module {@linkplain
-   * #annotation() annotations}.
-   *
-   * @throws IllegalArgumentException if the element is annotated with more than one of the module
-   *     annotations
-   */
-  static Optional<ModuleKind> forAnnotatedElement(TypeElement element) {
-    Set<ModuleKind> kinds = EnumSet.noneOf(ModuleKind.class);
-    for (ModuleKind kind : values()) {
-      if (MoreElements.isAnnotationPresent(element, kind.annotation())) {
-        kinds.add(kind);
-      }
-    }
-
-    if (kinds.size() > 1) {
-      throw new IllegalArgumentException(
-          element + " cannot be annotated with more than one of " + annotationsFor(kinds));
-    }
-    return kinds.stream().findAny();
-  }
-
-  static void checkIsModule(TypeElement moduleElement) {
-    checkArgument(forAnnotatedElement(moduleElement).isPresent());
-  }
-
-  private final Class<? extends Annotation> moduleAnnotation;
-
-  ModuleKind(Class<? extends Annotation> moduleAnnotation) {
-    this.moduleAnnotation = moduleAnnotation;
-  }
-
-  /**
-   * Returns the annotation mirror for this module kind on the given type.
-   *
-   * @throws IllegalArgumentException if the annotation is not present on the type
-   */
-  AnnotationMirror getModuleAnnotation(TypeElement element) {
-    Optional<AnnotationMirror> result = getAnnotationMirror(element, moduleAnnotation);
-    checkArgument(
-        result.isPresent(), "annotation %s is not present on type %s", moduleAnnotation, element);
-    return result.get();
-  }
-
-  /** Returns the annotation that marks a module of this kind. */
-  Class<? extends Annotation> annotation() {
-    return moduleAnnotation;
-  }
-
-  /** Returns the kinds of modules that a module of this kind is allowed to include. */
-  ImmutableSet<ModuleKind> legalIncludedModuleKinds() {
-    switch (this) {
-      case MODULE:
-        return Sets.immutableEnumSet(MODULE);
-      case PRODUCER_MODULE:
-        return Sets.immutableEnumSet(MODULE, PRODUCER_MODULE);
-    }
-    throw new AssertionError(this);
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleProcessingStep.java b/java/dagger/internal/codegen/ModuleProcessingStep.java
deleted file mode 100644
index 27cd531..0000000
--- a/java/dagger/internal/codegen/ModuleProcessingStep.java
+++ /dev/null
@@ -1,125 +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.auto.common.MoreElements.isAnnotationPresent;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-import static javax.lang.model.util.ElementFilter.typesIn;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.DelegateDeclaration.Factory;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.lang.annotation.Annotation;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A {@link ProcessingStep} that validates module classes and generates factories for binding
- * methods.
- */
-final class ModuleProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
-  private final Messager messager;
-  private final ModuleValidator moduleValidator;
-  private final BindingFactory bindingFactory;
-  private final SourceFileGenerator<ProvisionBinding> factoryGenerator;
-  private final SourceFileGenerator<ProductionBinding> producerFactoryGenerator;
-  private final SourceFileGenerator<TypeElement> moduleConstructorProxyGenerator;
-  private final InaccessibleMapKeyProxyGenerator inaccessibleMapKeyProxyGenerator;
-  private final DelegateDeclaration.Factory delegateDeclarationFactory;
-  private final Set<TypeElement> processedModuleElements = Sets.newLinkedHashSet();
-
-  @Inject
-  ModuleProcessingStep(
-      Messager messager,
-      ModuleValidator moduleValidator,
-      BindingFactory bindingFactory,
-      SourceFileGenerator<ProvisionBinding> factoryGenerator,
-      SourceFileGenerator<ProductionBinding> producerFactoryGenerator,
-      @ModuleGenerator SourceFileGenerator<TypeElement> moduleConstructorProxyGenerator,
-      InaccessibleMapKeyProxyGenerator inaccessibleMapKeyProxyGenerator,
-      Factory delegateDeclarationFactory) {
-    super(MoreElements::asType);
-    this.messager = messager;
-    this.moduleValidator = moduleValidator;
-    this.bindingFactory = bindingFactory;
-    this.factoryGenerator = factoryGenerator;
-    this.producerFactoryGenerator = producerFactoryGenerator;
-    this.moduleConstructorProxyGenerator = moduleConstructorProxyGenerator;
-    this.inaccessibleMapKeyProxyGenerator = inaccessibleMapKeyProxyGenerator;
-    this.delegateDeclarationFactory = delegateDeclarationFactory;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(Module.class, ProducerModule.class);
-  }
-
-  @Override
-  public ImmutableSet<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    List<TypeElement> modules = typesIn(elementsByAnnotation.values());
-    moduleValidator.addKnownModules(modules);
-    return super.process(elementsByAnnotation);
-  }
-
-  @Override
-  protected void process(
-      TypeElement module, ImmutableSet<Class<? extends Annotation>> annotations) {
-    if (processedModuleElements.contains(module)) {
-      return;
-    }
-    ValidationReport<TypeElement> report = moduleValidator.validate(module);
-    report.printMessagesTo(messager);
-    if (report.isClean()) {
-      for (ExecutableElement method : methodsIn(module.getEnclosedElements())) {
-        if (isAnnotationPresent(method, Provides.class)) {
-          generate(factoryGenerator, bindingFactory.providesMethodBinding(method, module));
-        } else if (isAnnotationPresent(method, Produces.class)) {
-          generate(producerFactoryGenerator, bindingFactory.producesMethodBinding(method, module));
-        } else if (isAnnotationPresent(method, Binds.class)) {
-          inaccessibleMapKeyProxyGenerator.generate(bindsMethodBinding(module, method), messager);
-        }
-      }
-      moduleConstructorProxyGenerator.generate(module, messager);
-    }
-    processedModuleElements.add(module);
-  }
-
-  private <B extends ContributionBinding> void generate(
-      SourceFileGenerator<B> generator, B binding) {
-    generator.generate(binding, messager);
-    inaccessibleMapKeyProxyGenerator.generate(binding, messager);
-  }
-
-  private ContributionBinding bindsMethodBinding(TypeElement module, ExecutableElement method) {
-    return bindingFactory.unresolvedDelegateBinding(
-        delegateDeclarationFactory.create(method, module));
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleProxies.java b/java/dagger/internal/codegen/ModuleProxies.java
deleted file mode 100644
index 6426e69..0000000
--- a/java/dagger/internal/codegen/ModuleProxies.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.constructorsIn;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.langmodel.Accessibility;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Optional;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/** Convenience methods for generating and using module constructor proxy methods. */
-final class ModuleProxies {
-  /** The name of the class that hosts the module constructor proxy method. */
-  static ClassName constructorProxyTypeName(TypeElement moduleElement) {
-    ModuleKind.checkIsModule(moduleElement);
-    ClassName moduleClassName = ClassName.get(moduleElement);
-    return moduleClassName
-        .topLevelClassName()
-        .peerClass(SourceFiles.classFileName(moduleClassName) + "_Proxy");
-  }
-
-  /**
-   * The module constructor being proxied. A proxy is generated if it is not publicly accessible and
-   * has no arguments. If an implicit reference to the enclosing class exists, or the module is
-   * abstract, no proxy method can be generated.
-   */
-  // TODO(ronshapiro): make this an @Injectable class that injects DaggerElements
-  static Optional<ExecutableElement> nonPublicNullaryConstructor(
-      TypeElement moduleElement, DaggerElements elements) {
-    ModuleKind.checkIsModule(moduleElement);
-    if (moduleElement.getModifiers().contains(ABSTRACT)
-        || (moduleElement.getNestingKind().isNested()
-            && !moduleElement.getModifiers().contains(STATIC))) {
-      return Optional.empty();
-    }
-    return constructorsIn(elements.getAllMembers(moduleElement)).stream()
-        .filter(constructor -> !Accessibility.isElementPubliclyAccessible(constructor))
-        .filter(constructor -> !constructor.getModifiers().contains(PRIVATE))
-        .filter(constructor -> constructor.getParameters().isEmpty())
-        .findAny();
-  }
-
-  /**
-   * Returns a code block that creates a new module instance, either by invoking the nullary
-   * constructor if it's accessible from {@code requestingClass} or else by invoking the
-   * constructor's generated proxy method.
-   */
-  static CodeBlock newModuleInstance(
-      TypeElement moduleElement, ClassName requestingClass, DaggerElements elements) {
-    ModuleKind.checkIsModule(moduleElement);
-    String packageName = requestingClass.packageName();
-    return nonPublicNullaryConstructor(moduleElement, elements)
-        .filter(constructor -> !isElementAccessibleFrom(constructor, packageName))
-        .map(
-            constructor ->
-                CodeBlock.of("$T.newInstance()", constructorProxyTypeName(moduleElement)))
-        .orElse(CodeBlock.of("new $T()", moduleElement));
-  }
-}
diff --git a/java/dagger/internal/codegen/ModuleValidator.java b/java/dagger/internal/codegen/ModuleValidator.java
deleted file mode 100644
index 094bf34..0000000
--- a/java/dagger/internal/codegen/ModuleValidator.java
+++ /dev/null
@@ -1,644 +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.auto.common.AnnotationMirrors.getAnnotatedAnnotations;
-import static com.google.auto.common.Visibility.PRIVATE;
-import static com.google.auto.common.Visibility.PUBLIC;
-import static com.google.auto.common.Visibility.effectiveVisibilityOfElement;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.ComponentAnnotation.componentAnnotation;
-import static dagger.internal.codegen.ComponentAnnotation.isComponentAnnotation;
-import static dagger.internal.codegen.ComponentAnnotation.subcomponentAnnotation;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.getCreatorAnnotations;
-import static dagger.internal.codegen.ConfigurationAnnotations.getSubcomponentCreator;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ModuleAnnotation.isModuleAnnotation;
-import static dagger.internal.codegen.ModuleAnnotation.moduleAnnotation;
-import static dagger.internal.codegen.MoreAnnotationMirrors.simpleName;
-import static dagger.internal.codegen.MoreAnnotationValues.asType;
-import static dagger.internal.codegen.Util.reentrantComputeIfAbsent;
-import static dagger.internal.codegen.ValidationType.NONE;
-import static dagger.internal.codegen.langmodel.DaggerElements.getAnnotationMirror;
-import static dagger.internal.codegen.langmodel.DaggerElements.isAnyAnnotationPresent;
-import static java.util.EnumSet.noneOf;
-import static java.util.stream.Collectors.joining;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.STATIC;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.common.Visibility;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Sets;
-import com.google.errorprone.annotations.FormatMethod;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingGraph;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Scope;
-import javax.inject.Singleton;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ElementKind;
-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.SimpleAnnotationValueVisitor8;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * A {@linkplain ValidationReport validator} for {@link Module}s or {@link ProducerModule}s.
- */
-@Singleton
-final class ModuleValidator {
-  private static final ImmutableSet<Class<? extends Annotation>> SUBCOMPONENT_TYPES =
-      ImmutableSet.of(Subcomponent.class, ProductionSubcomponent.class);
-  private static final ImmutableSet<Class<? extends Annotation>> SUBCOMPONENT_CREATOR_TYPES =
-      ImmutableSet.of(
-          Subcomponent.Builder.class,
-          Subcomponent.Factory.class,
-          ProductionSubcomponent.Builder.class,
-          ProductionSubcomponent.Factory.class);
-  private static final Optional<Class<?>> ANDROID_PROCESSOR;
-  private static final String CONTRIBUTES_ANDROID_INJECTOR_NAME =
-      "dagger.android.ContributesAndroidInjector";
-  private static final String ANDROID_PROCESSOR_NAME = "dagger.android.processor.AndroidProcessor";
-
-  static {
-    Class<?> clazz;
-    try {
-      clazz = Class.forName(ANDROID_PROCESSOR_NAME, false, ModuleValidator.class.getClassLoader());
-    } catch (ClassNotFoundException ignored) {
-      clazz = null;
-    }
-    ANDROID_PROCESSOR = Optional.ofNullable(clazz);
-  }
-
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final AnyBindingMethodValidator anyBindingMethodValidator;
-  private final MethodSignatureFormatter methodSignatureFormatter;
-  private final ComponentDescriptorFactory componentDescriptorFactory;
-  private final BindingGraphFactory bindingGraphFactory;
-  private final BindingGraphConverter bindingGraphConverter;
-  private final BindingGraphValidator bindingGraphValidator;
-  private final CompilerOptions compilerOptions;
-  private final Map<TypeElement, ValidationReport<TypeElement>> cache = new HashMap<>();
-  private final Set<TypeElement> knownModules = new HashSet<>();
-
-  @Inject
-  ModuleValidator(
-      DaggerTypes types,
-      DaggerElements elements,
-      AnyBindingMethodValidator anyBindingMethodValidator,
-      MethodSignatureFormatter methodSignatureFormatter,
-      ComponentDescriptorFactory componentDescriptorFactory,
-      BindingGraphFactory bindingGraphFactory,
-      BindingGraphConverter bindingGraphConverter,
-      BindingGraphValidator bindingGraphValidator,
-      CompilerOptions compilerOptions) {
-    this.types = types;
-    this.elements = elements;
-    this.anyBindingMethodValidator = anyBindingMethodValidator;
-    this.methodSignatureFormatter = methodSignatureFormatter;
-    this.componentDescriptorFactory = componentDescriptorFactory;
-    this.bindingGraphFactory = bindingGraphFactory;
-    this.bindingGraphConverter = bindingGraphConverter;
-    this.bindingGraphValidator = bindingGraphValidator;
-    this.compilerOptions = compilerOptions;
-  }
-
-  /**
-   * Adds {@code modules} to the set of module types that will be validated during this compilation
-   * step. If a component or module includes a module that is not in this set, that included module
-   * is assumed to be valid because it was processed in a previous compilation step. If it were
-   * invalid, that previous compilation step would have failed and blocked this one.
-   *
-   * <p>This logic depends on this method being called before {@linkplain #validate(TypeElement)
-   * validating} any module or {@linkplain #validateReferencedModules(TypeElement, AnnotationMirror,
-   * ImmutableSet, Set) component}.
-   */
-  void addKnownModules(Collection<TypeElement> modules) {
-    knownModules.addAll(modules);
-  }
-
-  /** Returns a validation report for a module type. */
-  ValidationReport<TypeElement> validate(TypeElement module) {
-    return validate(module, new HashSet<>());
-  }
-
-  private ValidationReport<TypeElement> validate(
-      TypeElement module, Set<TypeElement> visitedModules) {
-    if (visitedModules.add(module)) {
-      return reentrantComputeIfAbsent(cache, module, m -> validateUncached(module, visitedModules));
-    }
-    return ValidationReport.about(module).build();
-  }
-
-  private ValidationReport<TypeElement> validateUncached(
-      TypeElement module, Set<TypeElement> visitedModules) {
-    ValidationReport.Builder<TypeElement> builder = ValidationReport.about(module);
-    ModuleKind moduleKind = ModuleKind.forAnnotatedElement(module).get();
-
-    ListMultimap<String, ExecutableElement> allMethodsByName = ArrayListMultimap.create();
-    ListMultimap<String, ExecutableElement> bindingMethodsByName = ArrayListMultimap.create();
-
-    Set<ModuleMethodKind> methodKinds = noneOf(ModuleMethodKind.class);
-    TypeElement contributesAndroidInjectorElement =
-        elements.getTypeElement(CONTRIBUTES_ANDROID_INJECTOR_NAME);
-    TypeMirror contributesAndroidInjector =
-        contributesAndroidInjectorElement != null
-            ? contributesAndroidInjectorElement.asType()
-            : null;
-    for (ExecutableElement moduleMethod : methodsIn(module.getEnclosedElements())) {
-      if (anyBindingMethodValidator.isBindingMethod(moduleMethod)) {
-        builder.addSubreport(anyBindingMethodValidator.validate(moduleMethod));
-        bindingMethodsByName.put(moduleMethod.getSimpleName().toString(), moduleMethod);
-        methodKinds.add(ModuleMethodKind.ofMethod(moduleMethod));
-      }
-      allMethodsByName.put(moduleMethod.getSimpleName().toString(), moduleMethod);
-
-      for (AnnotationMirror annotation : moduleMethod.getAnnotationMirrors()) {
-        if (!ANDROID_PROCESSOR.isPresent()
-            && MoreTypes.equivalence()
-                .equivalent(contributesAndroidInjector, annotation.getAnnotationType())) {
-          builder.addSubreport(
-              ValidationReport.about(moduleMethod)
-                  .addError(
-                      String.format(
-                          "@%s was used, but %s was not found on the processor path",
-                          CONTRIBUTES_ANDROID_INJECTOR_NAME, ANDROID_PROCESSOR_NAME))
-                  .build());
-          break;
-        }
-      }
-    }
-
-    if (methodKinds.containsAll(
-        EnumSet.of(ModuleMethodKind.ABSTRACT_DECLARATION, ModuleMethodKind.INSTANCE_BINDING))) {
-      builder.addError(
-          String.format(
-              "A @%s may not contain both non-static and abstract binding methods",
-              moduleKind.annotation().getSimpleName()));
-    }
-
-    validateModuleVisibility(module, moduleKind, builder);
-    validateMethodsWithSameName(builder, bindingMethodsByName);
-    if (module.getKind() != ElementKind.INTERFACE) {
-      validateBindingMethodOverrides(module, builder, allMethodsByName, bindingMethodsByName);
-    }
-    validateModifiers(module, builder);
-    validateReferencedModules(module, moduleKind, visitedModules, builder);
-    validateReferencedSubcomponents(module, moduleKind, builder);
-    validateNoScopeAnnotationsOnModuleElement(module, moduleKind, builder);
-    validateSelfCycles(module, builder);
-
-    if (builder.build().isClean()
-        && !compilerOptions.fullBindingGraphValidationType(module).equals(NONE)) {
-      validateModuleBindings(module, builder);
-    }
-
-    return builder.build();
-  }
-
-  private void validateReferencedSubcomponents(
-      final TypeElement subject,
-      ModuleKind moduleKind,
-      final ValidationReport.Builder<TypeElement> builder) {
-    // TODO(ronshapiro): use validateTypesAreDeclared when it is checked in
-    ModuleAnnotation moduleAnnotation = moduleAnnotation(moduleKind.getModuleAnnotation(subject));
-    for (AnnotationValue subcomponentAttribute :
-        moduleAnnotation.subcomponentsAsAnnotationValues()) {
-      asType(subcomponentAttribute)
-          .accept(
-              new SimpleTypeVisitor8<Void, Void>() {
-                @Override
-                protected Void defaultAction(TypeMirror e, Void aVoid) {
-                  builder.addError(
-                      e + " is not a valid subcomponent type",
-                      subject,
-                      moduleAnnotation.annotation(),
-                      subcomponentAttribute);
-                  return null;
-                }
-
-                @Override
-                public Void visitDeclared(DeclaredType declaredType, Void aVoid) {
-                  TypeElement attributeType = MoreTypes.asTypeElement(declaredType);
-                  if (isAnyAnnotationPresent(attributeType, SUBCOMPONENT_TYPES)) {
-                    validateSubcomponentHasBuilder(
-                        attributeType, moduleAnnotation.annotation(), builder);
-                  } else {
-                    builder.addError(
-                        isAnyAnnotationPresent(attributeType, SUBCOMPONENT_CREATOR_TYPES)
-                            ? moduleSubcomponentsIncludesCreator(attributeType)
-                            : moduleSubcomponentsIncludesNonSubcomponent(attributeType),
-                        subject,
-                        moduleAnnotation.annotation(),
-                        subcomponentAttribute);
-                  }
-
-                  return null;
-                }
-              },
-              null);
-    }
-  }
-
-  private static String moduleSubcomponentsIncludesNonSubcomponent(TypeElement notSubcomponent) {
-    return notSubcomponent.getQualifiedName()
-        + " is not a @Subcomponent or @ProductionSubcomponent";
-  }
-
-  private static String moduleSubcomponentsIncludesCreator(
-      TypeElement moduleSubcomponentsAttribute) {
-    TypeElement subcomponentType =
-        MoreElements.asType(moduleSubcomponentsAttribute.getEnclosingElement());
-    ComponentCreatorAnnotation creatorAnnotation =
-        getOnlyElement(getCreatorAnnotations(moduleSubcomponentsAttribute));
-    return String.format(
-        "%s is a @%s.%s. Did you mean to use %s?",
-        moduleSubcomponentsAttribute.getQualifiedName(),
-        subcomponentAnnotation(subcomponentType).get().simpleName(),
-        creatorAnnotation.creatorKind().typeName(),
-        subcomponentType.getQualifiedName());
-  }
-
-  private static void validateSubcomponentHasBuilder(
-      TypeElement subcomponentAttribute,
-      AnnotationMirror moduleAnnotation,
-      ValidationReport.Builder<TypeElement> builder) {
-    if (getSubcomponentCreator(subcomponentAttribute).isPresent()) {
-      return;
-    }
-    builder.addError(
-        moduleSubcomponentsDoesntHaveCreator(subcomponentAttribute, moduleAnnotation),
-        builder.getSubject(),
-        moduleAnnotation);
-  }
-
-  private static String moduleSubcomponentsDoesntHaveCreator(
-      TypeElement subcomponent, AnnotationMirror moduleAnnotation) {
-    return String.format(
-        "%1$s doesn't have a @%2$s.Builder or @%2$s.Factory, which is required when used with "
-            + "@%3$s.subcomponents",
-        subcomponent.getQualifiedName(),
-        subcomponentAnnotation(subcomponent).get().simpleName(),
-        simpleName(moduleAnnotation));
-  }
-
-  enum ModuleMethodKind {
-    ABSTRACT_DECLARATION,
-    INSTANCE_BINDING,
-    STATIC_BINDING,
-    ;
-
-    static ModuleMethodKind ofMethod(ExecutableElement moduleMethod) {
-      if (moduleMethod.getModifiers().contains(STATIC)) {
-        return STATIC_BINDING;
-      } else if (moduleMethod.getModifiers().contains(ABSTRACT)) {
-        return ABSTRACT_DECLARATION;
-      } else {
-        return INSTANCE_BINDING;
-      }
-    }
-  }
-
-  private void validateModifiers(
-      TypeElement subject, ValidationReport.Builder<TypeElement> builder) {
-    // This coupled with the check for abstract modules in ComponentValidator guarantees that
-    // only modules without type parameters are referenced from @Component(modules={...}).
-    if (!subject.getTypeParameters().isEmpty() && !subject.getModifiers().contains(ABSTRACT)) {
-      builder.addError("Modules with type parameters must be abstract", subject);
-    }
-  }
-
-  private void validateMethodsWithSameName(
-      ValidationReport.Builder<TypeElement> builder,
-      ListMultimap<String, ExecutableElement> bindingMethodsByName) {
-    for (Entry<String, Collection<ExecutableElement>> entry :
-        bindingMethodsByName.asMap().entrySet()) {
-      if (entry.getValue().size() > 1) {
-        for (ExecutableElement offendingMethod : entry.getValue()) {
-          builder.addError(
-              String.format(
-                  "Cannot have more than one binding method with the same name in a single module"),
-              offendingMethod);
-        }
-      }
-    }
-  }
-
-  private void validateReferencedModules(
-      TypeElement subject,
-      ModuleKind moduleKind,
-      Set<TypeElement> visitedModules,
-      ValidationReport.Builder<TypeElement> builder) {
-    // Validate that all the modules we include are valid for inclusion.
-    AnnotationMirror mirror = moduleKind.getModuleAnnotation(subject);
-    builder.addSubreport(
-        validateReferencedModules(
-            subject, mirror, moduleKind.legalIncludedModuleKinds(), visitedModules));
-  }
-
-  /**
-   * Validates modules included in a given module or installed in a given component.
-   *
-   * <p>Checks that the referenced modules are non-generic types annotated with {@code @Module} or
-   * {@code @ProducerModule}.
-   *
-   * <p>If the referenced module is in the {@linkplain #addKnownModules(Collection) known modules
-   * set} and has errors, reports an error at that module's inclusion.
-   *
-   * @param annotatedType the annotated module or component
-   * @param annotation the annotation specifying the referenced modules ({@code @Component},
-   *     {@code @ProductionComponent}, {@code @Subcomponent}, {@code @ProductionSubcomponent},
-   *     {@code @Module}, or {@code @ProducerModule})
-   * @param validModuleKinds the module kinds that the annotated type is permitted to include
-   */
-  ValidationReport<TypeElement> validateReferencedModules(
-      TypeElement annotatedType,
-      AnnotationMirror annotation,
-      ImmutableSet<ModuleKind> validModuleKinds,
-      Set<TypeElement> visitedModules) {
-    ValidationReport.Builder<TypeElement> subreport = ValidationReport.about(annotatedType);
-    ImmutableSet<? extends Class<? extends Annotation>> validModuleAnnotations =
-        validModuleKinds.stream().map(ModuleKind::annotation).collect(toImmutableSet());
-
-    for (AnnotationValue includedModule : getModules(annotation)) {
-      asType(includedModule)
-          .accept(
-              new SimpleTypeVisitor8<Void, Void>() {
-                @Override
-                protected Void defaultAction(TypeMirror mirror, Void p) {
-                  reportError("%s is not a valid module type.", mirror);
-                  return null;
-                }
-
-                @Override
-                public Void visitDeclared(DeclaredType t, Void p) {
-                  TypeElement module = MoreElements.asType(t.asElement());
-                  if (!t.getTypeArguments().isEmpty()) {
-                    reportError(
-                        "%s is listed as a module, but has type parameters",
-                        module.getQualifiedName());
-                  }
-                  if (!isAnyAnnotationPresent(module, validModuleAnnotations)) {
-                    reportError(
-                        "%s is listed as a module, but is not annotated with %s",
-                        module.getQualifiedName(),
-                        (validModuleAnnotations.size() > 1 ? "one of " : "")
-                            + validModuleAnnotations
-                                .stream()
-                                .map(otherClass -> "@" + otherClass.getSimpleName())
-                                .collect(joining(", ")));
-                  } else if (knownModules.contains(module)
-                      && !validate(module, visitedModules).isClean()) {
-                    reportError("%s has errors", module.getQualifiedName());
-                  }
-                  return null;
-                }
-
-                @FormatMethod
-                private void reportError(String format, Object... args) {
-                  subreport.addError(
-                      String.format(format, args), annotatedType, annotation, includedModule);
-                }
-              },
-              null);
-    }
-    return subreport.build();
-  }
-
-  private static ImmutableList<AnnotationValue> getModules(AnnotationMirror annotation) {
-    if (isModuleAnnotation(annotation)) {
-      return moduleAnnotation(annotation).includesAsAnnotationValues();
-    }
-    if (isComponentAnnotation(annotation)) {
-      return componentAnnotation(annotation).moduleValues();
-    }
-    throw new IllegalArgumentException(String.format("unsupported annotation: %s", annotation));
-  }
-
-  private void validateBindingMethodOverrides(
-      TypeElement subject,
-      ValidationReport.Builder<TypeElement> builder,
-      ListMultimap<String, ExecutableElement> allMethodsByName,
-      ListMultimap<String, ExecutableElement> bindingMethodsByName) {
-    // For every binding method, confirm it overrides nothing *and* nothing overrides it.
-    // Consider the following hierarchy:
-    // class Parent {
-    //    @Provides Foo a() {}
-    //    @Provides Foo b() {}
-    //    Foo c() {}
-    // }
-    // class Child extends Parent {
-    //    @Provides Foo a() {}
-    //    Foo b() {}
-    //    @Provides Foo c() {}
-    // }
-    // In each of those cases, we want to fail.  "a" is clear, "b" because Child is overriding
-    // a binding method in Parent, and "c" because Child is defining a binding method that overrides
-    // Parent.
-    TypeElement currentClass = subject;
-    TypeMirror objectType = elements.getTypeElement(Object.class).asType();
-    // We keep track of methods that failed so we don't spam with multiple failures.
-    Set<ExecutableElement> failedMethods = Sets.newHashSet();
-    while (!types.isSameType(currentClass.getSuperclass(), objectType)) {
-      currentClass = MoreElements.asType(types.asElement(currentClass.getSuperclass()));
-      List<ExecutableElement> superclassMethods = methodsIn(currentClass.getEnclosedElements());
-      for (ExecutableElement superclassMethod : superclassMethods) {
-        String name = superclassMethod.getSimpleName().toString();
-        // For each method in the superclass, confirm our binding methods don't override it
-        for (ExecutableElement bindingMethod : bindingMethodsByName.get(name)) {
-          if (failedMethods.add(bindingMethod)
-              && elements.overrides(bindingMethod, superclassMethod, subject)) {
-            builder.addError(
-                String.format(
-                    "Binding methods may not override another method. Overrides: %s",
-                    methodSignatureFormatter.format(superclassMethod)),
-                bindingMethod);
-          }
-        }
-        // For each binding method in superclass, confirm our methods don't override it.
-        if (anyBindingMethodValidator.isBindingMethod(superclassMethod)) {
-          for (ExecutableElement method : allMethodsByName.get(name)) {
-            if (failedMethods.add(method)
-                && elements.overrides(method, superclassMethod, subject)) {
-              builder.addError(
-                  String.format(
-                      "Binding methods may not be overridden in modules. Overrides: %s",
-                      methodSignatureFormatter.format(superclassMethod)),
-                  method);
-            }
-          }
-        }
-        allMethodsByName.put(superclassMethod.getSimpleName().toString(), superclassMethod);
-      }
-    }
-  }
-
-  private void validateModuleVisibility(
-      final TypeElement moduleElement,
-      ModuleKind moduleKind,
-      final ValidationReport.Builder<?> reportBuilder) {
-    ModuleAnnotation moduleAnnotation =
-        moduleAnnotation(getAnnotationMirror(moduleElement, moduleKind.annotation()).get());
-    Visibility moduleVisibility = Visibility.ofElement(moduleElement);
-    Visibility moduleEffectiveVisibility = effectiveVisibilityOfElement(moduleElement);
-    if (moduleVisibility.equals(PRIVATE)) {
-      reportBuilder.addError("Modules cannot be private.", moduleElement);
-    } else if (moduleEffectiveVisibility.equals(PRIVATE)) {
-      reportBuilder.addError("Modules cannot be enclosed in private types.", moduleElement);
-    }
-
-    switch (moduleElement.getNestingKind()) {
-      case ANONYMOUS:
-        throw new IllegalStateException("Can't apply @Module to an anonymous class");
-      case LOCAL:
-        throw new IllegalStateException("Local classes shouldn't show up in the processor");
-      case MEMBER:
-      case TOP_LEVEL:
-        if (moduleEffectiveVisibility.equals(PUBLIC)) {
-          ImmutableSet<TypeElement> invalidVisibilityIncludes =
-              getModuleIncludesWithInvalidVisibility(moduleAnnotation);
-          if (!invalidVisibilityIncludes.isEmpty()) {
-            reportBuilder.addError(
-                String.format(
-                    "This module is public, but it includes non-public (or effectively non-public) "
-                        + "modules (%s) that have non-static, non-abstract binding methods. Either "
-                        + "reduce the visibility of this module, make the included modules "
-                        + "public, or make all of the binding methods on the included modules "
-                        + "abstract or static.",
-                    formatListForErrorMessage(invalidVisibilityIncludes.asList())),
-                moduleElement);
-          }
-        }
-    }
-  }
-
-  private ImmutableSet<TypeElement> getModuleIncludesWithInvalidVisibility(
-      ModuleAnnotation moduleAnnotation) {
-    return moduleAnnotation.includes().stream()
-        .filter(include -> !effectiveVisibilityOfElement(include).equals(PUBLIC))
-        .filter(this::requiresModuleInstance)
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns {@code true} if a module instance is needed for any of the binding methods on the
-   * given {@code module}. This is the case when the module has any binding methods that are neither
-   * {@code abstract} nor {@code static}.
-   */
-  private boolean requiresModuleInstance(TypeElement module) {
-    // Note elements.getAllMembers(module) rather than module.getEnclosedElements() here: we need to
-    // include binding methods declared in supertypes because unlike most other validations being
-    // done in this class, which assume that supertype binding methods will be validated in a
-    // separate call to the validator since the supertype itself must be a @Module, we need to look
-    // at all the binding methods in the module's type hierarchy here.
-    return methodsIn(elements.getAllMembers(module)).stream()
-        .filter(method -> anyBindingMethodValidator.isBindingMethod(method))
-        .map(ExecutableElement::getModifiers)
-        .anyMatch(modifiers -> !modifiers.contains(ABSTRACT) && !modifiers.contains(STATIC));
-  }
-
-  private void validateNoScopeAnnotationsOnModuleElement(
-      TypeElement module, ModuleKind moduleKind, ValidationReport.Builder<TypeElement> report) {
-    for (AnnotationMirror scope : getAnnotatedAnnotations(module, Scope.class)) {
-      report.addError(
-          String.format(
-              "@%ss cannot be scoped. Did you mean to scope a method instead?",
-              moduleKind.annotation().getSimpleName()),
-          module,
-          scope);
-    }
-  }
-
-  private void validateSelfCycles(
-      TypeElement module, ValidationReport.Builder<TypeElement> builder) {
-    ModuleAnnotation moduleAnnotation = moduleAnnotation(module).get();
-    moduleAnnotation
-        .includesAsAnnotationValues()
-        .forEach(
-            value ->
-                value.accept(
-                    new SimpleAnnotationValueVisitor8<Void, Void>() {
-                      @Override
-                      public Void visitType(TypeMirror includedModule, Void aVoid) {
-                        if (MoreTypes.equivalence().equivalent(module.asType(), includedModule)) {
-                          String moduleKind = moduleAnnotation.annotationClass().getSimpleName();
-                          builder.addError(
-                              String.format("@%s cannot include themselves.", moduleKind),
-                              module,
-                              moduleAnnotation.annotation(),
-                              value);
-                        }
-                        return null;
-                      }
-                    },
-                    null));
-  }
-
-  private void validateModuleBindings(
-      TypeElement module, ValidationReport.Builder<TypeElement> report) {
-    BindingGraph bindingGraph =
-        bindingGraphConverter.convert(
-            bindingGraphFactory.create(
-                componentDescriptorFactory.moduleComponentDescriptor(module), true));
-    if (!bindingGraphValidator.isValid(bindingGraph)) {
-      // Since the validator uses a DiagnosticReporter to report errors, the ValdiationReport won't
-      // have any Items for them. We have to tell the ValidationReport that some errors were
-      // reported for the subject.
-      report.markDirty();
-    }
-  }
-
-  private static String formatListForErrorMessage(List<?> things) {
-    switch (things.size()) {
-      case 0:
-        return "";
-      case 1:
-        return things.get(0).toString();
-      default:
-        StringBuilder output = new StringBuilder();
-        Joiner.on(", ").appendTo(output, things.subList(0, things.size() - 1));
-        output.append(" and ").append(things.get(things.size() - 1));
-        return output.toString();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/MonitoringModuleGenerator.java b/java/dagger/internal/codegen/MonitoringModuleGenerator.java
deleted file mode 100644
index 1738fe9..0000000
--- a/java/dagger/internal/codegen/MonitoringModuleGenerator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 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.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.javapoet.TypeNames.PRODUCTION_COMPONENT_MONITOR_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-import static dagger.internal.codegen.javapoet.TypeNames.setOf;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeSpec;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.multibindings.Multibinds;
-import dagger.producers.ProductionScope;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import dagger.producers.monitoring.internal.Monitors;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/** Generates a monitoring module for use with production components. */
-final class MonitoringModuleGenerator extends SourceFileGenerator<TypeElement> {
-
-  @Inject
-  MonitoringModuleGenerator(Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-  }
-
-  @Override
-  ClassName nameGeneratedType(TypeElement componentElement) {
-    return SourceFiles.generatedMonitoringModuleName(componentElement);
-  }
-
-  @Override
-  Element originatingElement(TypeElement componentElement) {
-    return componentElement;
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, TypeElement componentElement) {
-    return Optional.of(
-        classBuilder(generatedTypeName)
-            .addAnnotation(Module.class)
-            .addModifiers(ABSTRACT)
-            .addMethod(privateConstructor())
-            .addMethod(setOfFactories())
-            .addMethod(monitor(componentElement)));
-  }
-
-  private MethodSpec privateConstructor() {
-    return constructorBuilder().addModifiers(PRIVATE).build();
-  }
-
-  private MethodSpec setOfFactories() {
-    return methodBuilder("setOfFactories")
-        .addAnnotation(Multibinds.class)
-        .addModifiers(ABSTRACT)
-        .returns(setOf(PRODUCTION_COMPONENT_MONITOR_FACTORY))
-        .build();
-  }
-
-  private MethodSpec monitor(TypeElement componentElement) {
-    return methodBuilder("monitor")
-        .returns(ProductionComponentMonitor.class)
-        .addModifiers(STATIC)
-        .addAnnotation(Provides.class)
-        .addAnnotation(ProductionScope.class)
-        .addParameter(providerOf(ClassName.get(componentElement.asType())), "component")
-        .addParameter(
-            providerOf(setOf(PRODUCTION_COMPONENT_MONITOR_FACTORY)), "factories")
-        .addStatement(
-            "return $T.createMonitorForComponent(component, factories)", Monitors.class)
-        .build();
-  }
-}
diff --git a/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java b/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java
deleted file mode 100644
index 55ae579..0000000
--- a/java/dagger/internal/codegen/MonitoringModuleProcessingStep.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A processing step that is responsible for generating a special module for a {@link
- * ProductionComponent} or {@link ProductionSubcomponent}.
- */
-final class MonitoringModuleProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
-  private final Messager messager;
-  private final MonitoringModuleGenerator monitoringModuleGenerator;
-
-  @Inject
-  MonitoringModuleProcessingStep(
-      Messager messager, MonitoringModuleGenerator monitoringModuleGenerator) {
-    super(MoreElements::asType);
-    this.messager = messager;
-    this.monitoringModuleGenerator = monitoringModuleGenerator;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(ProductionComponent.class, ProductionSubcomponent.class);
-  }
-
-  @Override
-  protected void process(
-      TypeElement element, ImmutableSet<Class<? extends Annotation>> annotations) {
-      monitoringModuleGenerator.generate(MoreElements.asType(element), messager);
-  }
-}
diff --git a/java/dagger/internal/codegen/MoreAnnotationMirrors.java b/java/dagger/internal/codegen/MoreAnnotationMirrors.java
deleted file mode 100644
index 92825a0..0000000
--- a/java/dagger/internal/codegen/MoreAnnotationMirrors.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.AnnotationMirrors.getAnnotationValue;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.MoreAnnotationValues.asAnnotationValues;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.common.base.Equivalence;
-import com.google.common.collect.ImmutableList;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Name;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A utility class for working with {@link AnnotationMirror} instances, similar to {@link
- * AnnotationMirrors}.
- */
-final class MoreAnnotationMirrors {
-
-  private MoreAnnotationMirrors() {}
-
-  /**
-   * Wraps an {@link Optional} of a type in an {@code Optional} of a {@link Equivalence.Wrapper} for
-   * that type.
-   */
-  static Optional<Equivalence.Wrapper<AnnotationMirror>> wrapOptionalInEquivalence(
-      Optional<AnnotationMirror> optional) {
-    return optional.map(AnnotationMirrors.equivalence()::wrap);
-  }
-
-  /**
-   * Unwraps an {@link Optional} of a {@link Equivalence.Wrapper} into an {@code Optional} of the
-   * underlying type.
-   */
-  static Optional<AnnotationMirror> unwrapOptionalEquivalence(
-      Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedOptional) {
-    return wrappedOptional.map(Equivalence.Wrapper::get);
-  }
-
-  static Name simpleName(AnnotationMirror annotationMirror) {
-    return annotationMirror.getAnnotationType().asElement().getSimpleName();
-  }
-
-  /**
-   * Returns the list of types that is the value named {@code name} from {@code annotationMirror}.
-   *
-   * @throws IllegalArgumentException unless that member represents an array of types
-   */
-  static ImmutableList<TypeMirror> getTypeListValue(
-      AnnotationMirror annotationMirror, String name) {
-    return asAnnotationValues(getAnnotationValue(annotationMirror, name))
-        .stream()
-        .map(MoreAnnotationValues::asType)
-        .collect(toImmutableList());
-  }
-}
diff --git a/java/dagger/internal/codegen/MoreAnnotationValues.java b/java/dagger/internal/codegen/MoreAnnotationValues.java
deleted file mode 100644
index 84a4d94..0000000
--- a/java/dagger/internal/codegen/MoreAnnotationValues.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.google.common.collect.ImmutableList;
-import java.util.List;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-
-/** Utility methods for working with {@link AnnotationValue} instances. */
-final class MoreAnnotationValues {
-  /**
-   * Returns the list of values represented by an array annotation value.
-   *
-   * @throws IllegalArgumentException unless {@code annotationValue} represents an array
-   */
-  static ImmutableList<AnnotationValue> asAnnotationValues(AnnotationValue annotationValue) {
-    return annotationValue.accept(AS_ANNOTATION_VALUES, null);
-  }
-
-  private static final AnnotationValueVisitor<ImmutableList<AnnotationValue>, String>
-      AS_ANNOTATION_VALUES =
-          new SimpleAnnotationValueVisitor8<ImmutableList<AnnotationValue>, String>() {
-            @Override
-            public ImmutableList<AnnotationValue> visitArray(
-                List<? extends AnnotationValue> vals, String elementName) {
-              return ImmutableList.copyOf(vals);
-            }
-
-            @Override
-            protected ImmutableList<AnnotationValue> defaultAction(Object o, String elementName) {
-              throw new IllegalArgumentException(elementName + " is not an array: " + o);
-            }
-          };
-
-  /**
-   * Returns the type represented by an annotation value.
-   *
-   * @throws IllegalArgumentException unless {@code annotationValue} represents a single type
-   */
-  static TypeMirror asType(AnnotationValue annotationValue) {
-    return AS_TYPE.visit(annotationValue);
-  }
-
-  private static final AnnotationValueVisitor<TypeMirror, Void> AS_TYPE =
-      new SimpleAnnotationValueVisitor8<TypeMirror, Void>() {
-        @Override
-        public TypeMirror visitType(TypeMirror t, Void p) {
-          return t;
-        }
-
-        @Override
-        protected TypeMirror defaultAction(Object o, Void p) {
-          throw new TypeNotPresentException(o.toString(), null);
-        }
-      };
-
-  private MoreAnnotationValues() {}
-}
diff --git a/java/dagger/internal/codegen/MultibindingAnnotations.java b/java/dagger/internal/codegen/MultibindingAnnotations.java
deleted file mode 100644
index b478704..0000000
--- a/java/dagger/internal/codegen/MultibindingAnnotations.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.langmodel.DaggerElements.getAllAnnotations;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-
-/**
- * Utility methods related to processing {@link IntoSet}, {@link ElementsIntoSet}, and {@link
- * IntoMap}.
- */
-final class MultibindingAnnotations {
-  static ImmutableSet<AnnotationMirror> forElement(Element method) {
-    return getAllAnnotations(method, IntoSet.class, ElementsIntoSet.class, IntoMap.class);
-  }
-}
diff --git a/java/dagger/internal/codegen/MultibindingAnnotationsProcessingStep.java b/java/dagger/internal/codegen/MultibindingAnnotationsProcessingStep.java
deleted file mode 100644
index 2bb0a7e..0000000
--- a/java/dagger/internal/codegen/MultibindingAnnotationsProcessingStep.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.langmodel.DaggerElements.getAnnotationMirror;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.collect.ImmutableSet;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-
-/**
- * Processing step that verifies that {@link IntoSet}, {@link ElementsIntoSet} and {@link IntoMap}
- * are not present on non-binding methods.
- */
-final class MultibindingAnnotationsProcessingStep
-    extends TypeCheckingProcessingStep<ExecutableElement> {
-  private final AnyBindingMethodValidator anyBindingMethodValidator;
-  private final Messager messager;
-
-  @Inject
-  MultibindingAnnotationsProcessingStep(
-      AnyBindingMethodValidator anyBindingMethodValidator, Messager messager) {
-    super(MoreElements::asExecutable);
-    this.anyBindingMethodValidator = anyBindingMethodValidator;
-    this.messager = messager;
-  }
-
-  @Override
-  public Set<? extends Class<? extends Annotation>> annotations() {
-    return ImmutableSet.of(IntoSet.class, ElementsIntoSet.class, IntoMap.class);
-  }
-
-  @Override
-  protected void process(
-      ExecutableElement method, ImmutableSet<Class<? extends Annotation>> annotations) {
-    if (!anyBindingMethodValidator.isBindingMethod(method)) {
-      annotations.forEach(
-          annotation ->
-              messager.printMessage(
-                  ERROR,
-                  "Multibinding annotations may only be on @Provides, @Produces, or @Binds methods",
-                  method,
-                  getAnnotationMirror(method, annotation).get()));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/MultibindingDeclaration.java b/java/dagger/internal/codegen/MultibindingDeclaration.java
deleted file mode 100644
index c3724dc..0000000
--- a/java/dagger/internal/codegen/MultibindingDeclaration.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import dagger.internal.codegen.ContributionType.HasContributionType;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import dagger.multibindings.Multibinds;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A declaration that a multibinding with a certain key is available to be injected in a component
- * even if the component has no multibindings for that key. Identified by a map- or set-returning
- * method annotated with {@link Multibinds @Multibinds}.
- */
-@AutoValue
-abstract class MultibindingDeclaration extends BindingDeclaration implements HasContributionType {
-
-  /**
-   * The map or set key whose availability is declared. For maps, this will be {@code Map<K,
-   * Provider<V>>}. For sets, this will be {@code Set<T>}.
-   */
-  @Override
-  public abstract Key key();
-
-  /**
-   * {@link ContributionType#SET} if the declared type is a {@link Set}, or
-   * {@link ContributionType#MAP} if it is a {@link Map}.
-   */
-  @Override
-  public abstract ContributionType contributionType();
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-
-  /**
-   * A factory for {@link MultibindingDeclaration}s.
-   */
-  static final class Factory {
-    private final DaggerTypes types;
-    private final KeyFactory keyFactory;
-
-    @Inject
-    Factory(DaggerTypes types, KeyFactory keyFactory) {
-      this.types = types;
-      this.keyFactory = keyFactory;
-    }
-
-    /** A multibinding declaration for a {@link Multibinds @Multibinds} method. */
-    MultibindingDeclaration forMultibindsMethod(
-        ExecutableElement moduleMethod, TypeElement moduleElement) {
-      checkArgument(isAnnotationPresent(moduleMethod, Multibinds.class));
-      return forDeclaredMethod(
-          moduleMethod,
-          MoreTypes.asExecutable(
-              types.asMemberOf(MoreTypes.asDeclared(moduleElement.asType()), moduleMethod)),
-          moduleElement);
-    }
-
-    private MultibindingDeclaration forDeclaredMethod(
-        ExecutableElement method,
-        ExecutableType methodType,
-        TypeElement contributingType) {
-      TypeMirror returnType = methodType.getReturnType();
-      checkArgument(
-          SetType.isSet(returnType) || MapType.isMap(returnType),
-          "%s must return a set or map",
-          method);
-      return new AutoValue_MultibindingDeclaration(
-          Optional.<Element>of(method),
-          Optional.of(contributingType),
-          keyFactory.forMultibindsMethod(methodType, method),
-          contributionType(returnType));
-    }
-
-    private ContributionType contributionType(TypeMirror returnType) {
-      if (MapType.isMap(returnType)) {
-        return ContributionType.MAP;
-      } else if (SetType.isSet(returnType)) {
-        return ContributionType.SET;
-      } else {
-        throw new IllegalArgumentException("Must be Map or Set: " + returnType);
-      }
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/MultibindingExpression.java b/java/dagger/internal/codegen/MultibindingExpression.java
deleted file mode 100644
index f0523eb..0000000
--- a/java/dagger/internal/codegen/MultibindingExpression.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import java.util.Optional;
-import java.util.Set;
-
-/** An abstract base class for multibinding {@link BindingExpression}s. */
-abstract class MultibindingExpression extends SimpleInvocationBindingExpression {
-  private final ProvisionBinding binding;
-  private final ComponentImplementation componentImplementation;
-
-  MultibindingExpression(
-      ResolvedBindings resolvedBindings, ComponentImplementation componentImplementation) {
-    super(resolvedBindings);
-    this.componentImplementation = componentImplementation;
-    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    Expression expression = buildDependencyExpression(requestingClass);
-    componentImplementation.registerImplementedMultibinding(binding, bindingRequest());
-    return expression;
-  }
-
-  /**
-   * Returns an expression that evaluates to the value of a multibinding request for the given
-   * requesting class.
-   */
-  protected abstract Expression buildDependencyExpression(ClassName requestingClass);
-
-  /**
-   * Returns the subset of {@code dependencies} that represent multibinding contributions that were
-   * not included in a superclass implementation of this multibinding method. This is relevant only
-   * for ahead-of-time subcomponents. When not generating ahead-of-time subcomponents there is only
-   * one implementation of a multibinding expression and all {@link DependencyRequest}s from the
-   * argment are returned.
-   */
-  protected Set<DependencyRequest> getNewContributions(
-      ImmutableSet<DependencyRequest> dependencies) {
-    ImmutableSet<Key> superclassContributions = superclassContributions();
-    return Sets.filter(
-        dependencies, dependency -> !superclassContributions.contains(dependency.key()));
-  }
-
-  /**
-   * Returns the {@link CodeBlock} representing a call to a superclass implementation of the
-   * modifiable binding method that encapsulates this binding, if it exists. This is only possible
-   * when generating ahead-of-time subcomponents.
-   */
-  protected Optional<CodeBlock> superMethodCall() {
-    if (componentImplementation.superclassImplementation().isPresent()) {
-      Optional<ModifiableBindingMethod> method =
-          componentImplementation.getModifiableBindingMethod(bindingRequest());
-      if (method.isPresent()) {
-        if (!superclassContributions().isEmpty()) {
-          return Optional.of(CodeBlock.of("super.$L()", method.get().methodSpec().name));
-        }
-      }
-    }
-    return Optional.empty();
-  }
-
-  private BindingRequest bindingRequest() {
-    return BindingRequest.bindingRequest(binding.key(), RequestKind.INSTANCE);
-  }
-
-  private ImmutableSet<Key> superclassContributions() {
-    return componentImplementation.superclassContributionsMade(bindingRequest());
-  }
-}
diff --git a/java/dagger/internal/codegen/MultibindingFactoryCreationExpression.java b/java/dagger/internal/codegen/MultibindingFactoryCreationExpression.java
deleted file mode 100644
index abe161a..0000000
--- a/java/dagger/internal/codegen/MultibindingFactoryCreationExpression.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import java.util.Optional;
-
-/** An abstract factory creation expression for multibindings. */
-abstract class MultibindingFactoryCreationExpression
-    implements FrameworkInstanceCreationExpression {
-  private final ComponentImplementation componentImplementation;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final ContributionBinding binding;
-
-  MultibindingFactoryCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  /** Returns the expression for a dependency of this multibinding. */
-  protected final CodeBlock multibindingDependencyExpression(DependencyRequest dependency) {
-    CodeBlock expression =
-        componentBindingExpressions
-            .getDependencyExpression(
-                BindingRequest.bindingRequest(dependency.key(), binding.frameworkType()),
-                componentImplementation.name())
-            .codeBlock();
-
-    return useRawType()
-        ? CodeBlocks.cast(expression, binding.frameworkType().frameworkClass())
-        : expression;
-  }
-
-  protected final ImmutableSet<DependencyRequest> dependenciesToImplement() {
-    ImmutableSet<Key> alreadyImplementedKeys =
-        componentImplementation.superclassContributionsMade(bindingRequest());
-    return binding.dependencies().stream()
-        .filter(dependency -> !alreadyImplementedKeys.contains(dependency.key()))
-        .collect(toImmutableSet());
-  }
-
-  protected Optional<CodeBlock> superContributions() {
-    if (dependenciesToImplement().size() == binding.dependencies().size()) {
-      return Optional.empty();
-    }
-    ModifiableBindingMethod superMethod =
-        componentImplementation.getModifiableBindingMethod(bindingRequest()).get();
-    return Optional.of(CodeBlock.of("super.$N()", superMethod.methodSpec().name));
-  }
-
-  /** The binding request for this framework instance. */
-  protected final BindingRequest bindingRequest() {
-    return BindingRequest.bindingRequest(binding.key(), binding.frameworkType());
-  }
-
-  /**
-   * Returns true if the {@linkplain ContributionBinding#key() key type} is inaccessible from the
-   * component, and therefore a raw type must be used.
-   */
-  protected final boolean useRawType() {
-    return !componentImplementation.isTypeAccessible(binding.key().type());
-  }
-
-  @Override
-  public final boolean useInnerSwitchingProvider() {
-    return !binding.dependencies().isEmpty();
-  }
-}
diff --git a/java/dagger/internal/codegen/MultibindsMethodValidator.java b/java/dagger/internal/codegen/MultibindsMethodValidator.java
deleted file mode 100644
index bc97d30..0000000
--- a/java/dagger/internal/codegen/MultibindsMethodValidator.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.BindingElementValidator.AllowsMultibindings.NO_MULTIBINDINGS;
-import static dagger.internal.codegen.BindingElementValidator.AllowsScoping.NO_SCOPING;
-import static dagger.internal.codegen.BindingMethodValidator.Abstractness.MUST_BE_ABSTRACT;
-import static dagger.internal.codegen.BindingMethodValidator.ExceptionSuperclass.NO_EXCEPTIONS;
-import static dagger.internal.codegen.FrameworkTypes.isFrameworkType;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import dagger.Module;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.multibindings.Multibinds;
-import dagger.producers.ProducerModule;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for {@link Multibinds} methods. */
-class MultibindsMethodValidator extends BindingMethodValidator {
-
-  /** Creates a validator for {@link Multibinds @Multibinds} methods. */
-  @Inject
-  MultibindsMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator) {
-    super(
-        elements,
-        types,
-        Multibinds.class,
-        ImmutableSet.of(Module.class, ProducerModule.class),
-        dependencyRequestValidator,
-        MUST_BE_ABSTRACT,
-        NO_EXCEPTIONS,
-        NO_MULTIBINDINGS,
-        NO_SCOPING);
-  }
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends MethodValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkParameters() {
-      if (!element.getParameters().isEmpty()) {
-        report.addError(bindingMethods("cannot have parameters"));
-      }
-    }
-
-    /** Adds an error unless the method returns a {@code Map<K, V>} or {@code Set<T>}. */
-    @Override
-    protected void checkType() {
-      if (!isPlainMap(element.getReturnType())
-          && !isPlainSet(element.getReturnType())) {
-        report.addError(bindingMethods("must return Map<K, V> or Set<T>"));
-      }
-    }
-
-    private boolean isPlainMap(TypeMirror returnType) {
-      if (!MapType.isMap(returnType)) {
-        return false;
-      }
-      MapType mapType = MapType.from(returnType);
-      return !mapType.isRawType()
-          && MoreTypes.isType(mapType.valueType()) // No wildcards.
-          && !isFrameworkType(mapType.valueType());
-    }
-
-    private boolean isPlainSet(TypeMirror returnType) {
-      if (!SetType.isSet(returnType)) {
-        return false;
-      }
-      SetType setType = SetType.from(returnType);
-      return !setType.isRawType()
-          && MoreTypes.isType(setType.elementType()) // No wildcards.
-          && !isFrameworkType(setType.elementType());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/NullableBindingValidator.java b/java/dagger/internal/codegen/NullableBindingValidator.java
deleted file mode 100644
index 1452c3f..0000000
--- a/java/dagger/internal/codegen/NullableBindingValidator.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import javax.inject.Inject;
-
-/**
- * Reports errors or warnings (depending on the {@code -Adagger.nullableValidation} value) for each
- * non-nullable dependency request that is satisfied by a nullable binding.
- */
-final class NullableBindingValidator implements BindingGraphPlugin {
-
-  private final CompilerOptions compilerOptions;
-
-  @Inject
-  NullableBindingValidator(CompilerOptions compilerOptions) {
-    this.compilerOptions = compilerOptions;
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    for (dagger.model.Binding binding : nullableBindings(bindingGraph)) {
-      for (DependencyEdge dependencyEdge : nonNullableDependencies(bindingGraph, binding)) {
-        diagnosticReporter.reportDependency(
-            compilerOptions.nullableValidationKind(),
-            dependencyEdge,
-            nullableToNonNullable(
-                binding.key().toString(),
-                binding.toString())); // binding.toString() will include the @Nullable
-      }
-    }
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/Nullable";
-  }
-
-  private ImmutableList<dagger.model.Binding> nullableBindings(BindingGraph bindingGraph) {
-    return bindingGraph.bindings().stream()
-        .filter(binding -> binding.isNullable())
-        .collect(toImmutableList());
-  }
-
-  private ImmutableSet<DependencyEdge> nonNullableDependencies(
-      BindingGraph bindingGraph, dagger.model.Binding binding) {
-    return bindingGraph.network().inEdges(binding).stream()
-        .flatMap(instancesOf(DependencyEdge.class))
-        .filter(edge -> !edge.dependencyRequest().isNullable())
-        .collect(toImmutableSet());
-  }
-
-  @VisibleForTesting
-  static String nullableToNonNullable(String key, String binding) {
-    return String.format("%s is not nullable, but is being provided by %s", key, binding);
-  }
-}
diff --git a/java/dagger/internal/codegen/OptionalBindingDeclaration.java b/java/dagger/internal/codegen/OptionalBindingDeclaration.java
deleted file mode 100644
index b26ab91..0000000
--- a/java/dagger/internal/codegen/OptionalBindingDeclaration.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import dagger.BindsOptionalOf;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/** A {@link BindsOptionalOf} declaration. */
-@AutoValue
-abstract class OptionalBindingDeclaration extends BindingDeclaration {
-
-  /**
-   * {@inheritDoc}
-   *
-   * <p>The key's type is the method's return type, even though the synthetic bindings will be for
-   * {@code Optional} of derived types.
-   */
-  @Override
-  public abstract Key key();
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-
-  static class Factory {
-    private final KeyFactory keyFactory;
-
-    @Inject
-    Factory(KeyFactory keyFactory) {
-      this.keyFactory = keyFactory;
-    }
-
-    OptionalBindingDeclaration forMethod(ExecutableElement method, TypeElement contributingModule) {
-      checkArgument(isAnnotationPresent(method, BindsOptionalOf.class));
-      return new AutoValue_OptionalBindingDeclaration(
-          Optional.<Element>of(method),
-          Optional.of(contributingModule),
-          keyFactory.forBindsOptionalOfMethod(method, contributingModule));
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/OptionalBindingExpression.java b/java/dagger/internal/codegen/OptionalBindingExpression.java
deleted file mode 100644
index dbb0e37..0000000
--- a/java/dagger/internal/codegen/OptionalBindingExpression.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.OptionalType.OptionalKind;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-
-/** A binding expression for optional bindings. */
-final class OptionalBindingExpression extends SimpleInvocationBindingExpression {
-  private final ProvisionBinding binding;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-  private final SourceVersion sourceVersion;
-
-  @Inject
-  OptionalBindingExpression(
-      ResolvedBindings resolvedBindings,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      SourceVersion sourceVersion) {
-    super(resolvedBindings);
-    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.types = types;
-    this.sourceVersion = sourceVersion;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    OptionalType optionalType = OptionalType.from(binding.key());
-    OptionalKind optionalKind = optionalType.kind();
-    if (binding.dependencies().isEmpty()) {
-      if (sourceVersion.compareTo(SourceVersion.RELEASE_7) <= 0) {
-        // When compiling with -source 7, javac's type inference isn't strong enough to detect
-        // Futures.immediateFuture(Optional.absent()) for keys that aren't Object. It also has
-        // issues
-        // when used as an argument to some members injection proxy methods (see
-        // https://github.com/google/dagger/issues/916)
-        if (isTypeAccessibleFrom(binding.key().type(), requestingClass.packageName())) {
-          return Expression.create(
-              binding.key().type(), optionalKind.parameterizedAbsentValueExpression(optionalType));
-        }
-      }
-      return Expression.create(binding.key().type(), optionalKind.absentValueExpression());
-    }
-    DependencyRequest dependency = getOnlyElement(binding.dependencies());
-
-    CodeBlock dependencyExpression =
-        componentBindingExpressions
-            .getDependencyExpression(bindingRequest(dependency), requestingClass)
-            .codeBlock();
-
-    // If the dependency type is inaccessible, then we have to use Optional.<Object>of(...), or else
-    // we will get "incompatible types: inference variable has incompatible bounds.
-    return isTypeAccessibleFrom(dependency.key().type(), requestingClass.packageName())
-        ? Expression.create(
-            binding.key().type(), optionalKind.presentExpression(dependencyExpression))
-        : Expression.create(
-            types.erasure(binding.key().type()),
-            optionalKind.presentObjectExpression(dependencyExpression));
-  }
-
-  @Override
-  boolean requiresMethodEncapsulation() {
-    // TODO(dpb): Maybe require it for present bindings.
-    return false;
-  }
-}
diff --git a/java/dagger/internal/codegen/OptionalFactories.java b/java/dagger/internal/codegen/OptionalFactories.java
deleted file mode 100644
index 51c9939..0000000
--- a/java/dagger/internal/codegen/OptionalFactories.java
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright (C) 2016 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.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-import static com.google.common.base.Verify.verify;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.squareup.javapoet.MethodSpec.constructorBuilder;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.ComponentImplementation.FieldSpecKind.ABSENT_OPTIONAL_FIELD;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.ABSENT_OPTIONAL_METHOD;
-import static dagger.internal.codegen.ComponentImplementation.TypeSpecKind.PRESENT_FACTORY;
-import static dagger.internal.codegen.RequestKinds.requestTypeName;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER;
-import static dagger.internal.codegen.javapoet.TypeNames.abstractProducerOf;
-import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-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;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.internal.InstanceFactory;
-import dagger.internal.Preconditions;
-import dagger.internal.codegen.OptionalType.OptionalKind;
-import dagger.internal.codegen.javapoet.AnnotationSpecs;
-import dagger.model.RequestKind;
-import dagger.producers.Producer;
-import dagger.producers.internal.Producers;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.TreeMap;
-import java.util.concurrent.Executor;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/** The nested class and static methods required by the component to implement optional bindings. */
-// TODO(dpb): Name members simply if a component uses only one of Guava or JDK Optional.
-@PerGeneratedFile
-final class OptionalFactories {
-  private final ComponentImplementation componentImplementation;
-
-  @Inject OptionalFactories(@TopLevel ComponentImplementation componentImplementation) {
-    this.componentImplementation = componentImplementation;
-  }
-
-  /**
-   * The factory classes that implement {@code Provider<Optional<T>>} or {@code
-   * Producer<Optional<T>>} for present optional bindings for a given kind of dependency request
-   * within the component.
-   *
-   * <p>The key is the {@code Provider<Optional<T>>} type.
-   */
-  private final Map<PresentFactorySpec, TypeSpec> presentFactoryClasses =
-      new TreeMap<>(
-          Comparator.comparing(PresentFactorySpec::valueKind)
-              .thenComparing(PresentFactorySpec::frameworkType)
-              .thenComparing(PresentFactorySpec::optionalKind));
-
-  /**
-   * The static methods that return a {@code Provider<Optional<T>>} that always returns an absent
-   * value.
-   */
-  private final Map<OptionalKind, MethodSpec> absentOptionalProviderMethods = new TreeMap<>();
-
-  /**
-   * The static fields for {@code Provider<Optional<T>>} objects that always return an absent value.
-   */
-  private final Map<OptionalKind, FieldSpec> absentOptionalProviderFields = new TreeMap<>();
-
-  /**
-   * Returns an expression that calls a static method that returns a {@code Provider<Optional<T>>}
-   * for absent optional bindings.
-   */
-  CodeBlock absentOptionalProvider(ContributionBinding binding) {
-    verify(
-        binding.bindingType().equals(BindingType.PROVISION),
-        "Absent optional bindings should be provisions: %s",
-        binding);
-    OptionalKind optionalKind = OptionalType.from(binding.key()).kind();
-    return CodeBlock.of(
-        "$N()",
-        absentOptionalProviderMethods.computeIfAbsent(
-            optionalKind,
-            kind -> {
-              MethodSpec method = absentOptionalProviderMethod(kind);
-              componentImplementation.addMethod(ABSENT_OPTIONAL_METHOD, method);
-              return method;
-            }));
-  }
-
-  /**
-   * Creates a method specification for a {@code Provider<Optional<T>>} that always returns an
-   * absent value.
-   */
-  private MethodSpec absentOptionalProviderMethod(OptionalKind optionalKind) {
-    TypeVariableName typeVariable = TypeVariableName.get("T");
-    return methodBuilder(
-            String.format(
-                "absent%sProvider", UPPER_UNDERSCORE.to(UPPER_CAMEL, optionalKind.name())))
-        .addModifiers(PRIVATE, STATIC)
-        .addTypeVariable(typeVariable)
-        .returns(providerOf(optionalKind.of(typeVariable)))
-        .addJavadoc(
-            "Returns a {@link $T} that returns {@code $L}.",
-            Provider.class,
-            optionalKind.absentValueExpression())
-        .addCode("$L // safe covariant cast\n", AnnotationSpecs.suppressWarnings(UNCHECKED))
-        .addCode(
-            "$1T provider = ($1T) $2N;",
-            providerOf(optionalKind.of(typeVariable)),
-            absentOptionalProviderFields.computeIfAbsent(
-                optionalKind,
-                kind -> {
-                  FieldSpec field = absentOptionalProviderField(kind);
-                  componentImplementation.addField(ABSENT_OPTIONAL_FIELD, field);
-                  return field;
-                }))
-        .addCode("return provider;")
-        .build();
-  }
-
-  /**
-   * Creates a field specification for a {@code Provider<Optional<T>>} that always returns an absent
-   * value.
-   */
-  private FieldSpec absentOptionalProviderField(OptionalKind optionalKind) {
-    return FieldSpec.builder(
-            PROVIDER,
-            String.format("ABSENT_%s_PROVIDER", optionalKind.name()),
-            PRIVATE,
-            STATIC,
-            FINAL)
-        .addAnnotation(AnnotationSpecs.suppressWarnings(RAWTYPES))
-        .initializer("$T.create($L)", InstanceFactory.class, optionalKind.absentValueExpression())
-        .addJavadoc(
-            "A {@link $T} that returns {@code $L}.",
-            Provider.class,
-            optionalKind.absentValueExpression())
-        .build();
-  }
-
-  /** Information about the type of a factory for present bindings. */
-  @AutoValue
-  abstract static class PresentFactorySpec {
-    /** Whether the factory is a {@link Provider} or a {@link Producer}. */
-    abstract FrameworkType frameworkType();
-
-    /** What kind of {@code Optional} is returned. */
-    abstract OptionalKind optionalKind();
-
-    /** The kind of request satisfied by the value of the {@code Optional}. */
-    abstract RequestKind valueKind();
-
-    /** The type variable for the factory class. */
-    TypeVariableName typeVariable() {
-      return TypeVariableName.get("T");
-    }
-
-    /** The type contained by the {@code Optional}. */
-    TypeName valueType() {
-      return requestTypeName(valueKind(), typeVariable());
-    }
-
-    /** The type provided or produced by the factory. */
-    ParameterizedTypeName optionalType() {
-      return optionalKind().of(valueType());
-    }
-
-    /** The type of the factory. */
-    ParameterizedTypeName factoryType() {
-      return frameworkType().frameworkClassOf(optionalType());
-    }
-
-    /** The type of the delegate provider or producer. */
-    ParameterizedTypeName delegateType() {
-      return frameworkType().frameworkClassOf(typeVariable());
-    }
-
-    /** Returns the superclass the generated factory should have, if any. */
-    Optional<ParameterizedTypeName> superclass() {
-      switch (frameworkType()) {
-        case PRODUCER_NODE:
-          // TODO(cgdecker): This probably isn't a big issue for now, but it's possible this
-          // shouldn't be an AbstractProducer:
-          // - As AbstractProducer, it'll only call the delegate's get() method once and then cache
-          //   that result (essentially) rather than calling the delegate's get() method each time
-          //   its get() method is called (which was what it did before the cancellation change).
-          // - It's not 100% clear to me whether the view-creation methods should return a view of
-          //   the same view created by the delegate or if they should just return their own views.
-          return Optional.of(abstractProducerOf(optionalType()));
-        default:
-          return Optional.empty();
-      }
-    }
-
-    /** Returns the superinterface the generated factory should have, if any. */
-    Optional<ParameterizedTypeName> superinterface() {
-      switch (frameworkType()) {
-        case PROVIDER:
-          return Optional.of(factoryType());
-        default:
-          return Optional.empty();
-      }
-    }
-
-    /** Returns the name of the factory method to generate. */
-    String factoryMethodName() {
-      switch (frameworkType()) {
-        case PROVIDER:
-          return "get";
-        case PRODUCER_NODE:
-          return "compute";
-      }
-      throw new AssertionError(frameworkType());
-    }
-
-    /** The name of the factory class. */
-    String factoryClassName() {
-      return new StringBuilder("Present")
-          .append(UPPER_UNDERSCORE.to(UPPER_CAMEL, optionalKind().name()))
-          .append(UPPER_UNDERSCORE.to(UPPER_CAMEL, valueKind().toString()))
-          .append(frameworkType().frameworkClass().getSimpleName())
-          .toString();
-    }
-
-    private static PresentFactorySpec of(ContributionBinding binding) {
-      return new AutoValue_OptionalFactories_PresentFactorySpec(
-          FrameworkType.forBindingType(binding.bindingType()),
-          OptionalType.from(binding.key()).kind(),
-          getOnlyElement(binding.dependencies()).kind());
-    }
-  }
-
-  /**
-   * Returns an expression for an instance of a nested class that implements {@code
-   * Provider<Optional<T>>} or {@code Producer<Optional<T>>} for a present optional binding, where
-   * {@code T} represents dependency requests of that kind.
-   *
-   * <ul>
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#INSTANCE}, the class implements
-   *       {@code ProviderOrProducer<Optional<T>>}.
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#PROVIDER}, the class implements
-   *       {@code Provider<Optional<Provider<T>>>}.
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#LAZY}, the class implements {@code
-   *       Provider<Optional<Lazy<T>>>}.
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#PROVIDER_OF_LAZY}, the class
-   *       implements {@code Provider<Optional<Provider<Lazy<T>>>>}.
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#PRODUCER}, the class implements
-   *       {@code Producer<Optional<Producer<T>>>}.
-   *   <li>If {@code optionalRequestKind} is {@link RequestKind#PRODUCED}, the class implements
-   *       {@code Producer<Optional<Produced<T>>>}.
-   * </ul>
-   *
-   * @param delegateFactory an expression for a {@link Provider} or {@link Producer} of the
-   *     underlying type
-   */
-  CodeBlock presentOptionalFactory(ContributionBinding binding, CodeBlock delegateFactory) {
-    return CodeBlock.of(
-        "$N.of($L)",
-        presentFactoryClasses.computeIfAbsent(
-            PresentFactorySpec.of(binding),
-            spec -> {
-              TypeSpec type = presentOptionalFactoryClass(spec);
-              componentImplementation.addType(PRESENT_FACTORY, type);
-              return type;
-            }),
-        delegateFactory);
-  }
-
-  private TypeSpec presentOptionalFactoryClass(PresentFactorySpec spec) {
-    FieldSpec delegateField =
-        FieldSpec.builder(spec.delegateType(), "delegate", PRIVATE, FINAL).build();
-    ParameterSpec delegateParameter = ParameterSpec.builder(delegateField.type, "delegate").build();
-    TypeSpec.Builder factoryClassBuilder =
-        classBuilder(spec.factoryClassName())
-            .addTypeVariable(spec.typeVariable())
-            .addModifiers(PRIVATE, STATIC, FINAL)
-            .addJavadoc(
-                "A {@code $T} that uses a delegate {@code $T}.",
-                spec.factoryType(),
-                delegateField.type);
-
-    spec.superclass().ifPresent(factoryClassBuilder::superclass);
-    spec.superinterface().ifPresent(factoryClassBuilder::addSuperinterface);
-
-    return factoryClassBuilder
-        .addField(delegateField)
-        .addMethod(
-            constructorBuilder()
-                .addModifiers(PRIVATE)
-                .addParameter(delegateParameter)
-                .addCode(
-                    "this.$N = $T.checkNotNull($N);",
-                    delegateField,
-                    Preconditions.class,
-                    delegateParameter)
-                .build())
-        .addMethod(presentOptionalFactoryGetMethod(spec, delegateField))
-        .addMethod(
-            methodBuilder("of")
-                .addModifiers(PRIVATE, STATIC)
-                .addTypeVariable(spec.typeVariable())
-                .returns(spec.factoryType())
-                .addParameter(delegateParameter)
-                .addCode(
-                    "return new $L<$T>($N);",
-                    spec.factoryClassName(),
-                    spec.typeVariable(),
-                    delegateParameter)
-                .build())
-        .build();
-  }
-
-  private MethodSpec presentOptionalFactoryGetMethod(
-      PresentFactorySpec spec, FieldSpec delegateField) {
-    MethodSpec.Builder getMethodBuilder =
-        methodBuilder(spec.factoryMethodName()).addAnnotation(Override.class).addModifiers(PUBLIC);
-
-    switch (spec.frameworkType()) {
-      case PROVIDER:
-        return getMethodBuilder
-            .returns(spec.optionalType())
-            .addCode(
-                "return $L;",
-                spec.optionalKind()
-                    .presentExpression(
-                        FrameworkType.PROVIDER.to(
-                            spec.valueKind(), CodeBlock.of("$N", delegateField))))
-            .build();
-
-      case PRODUCER_NODE:
-        getMethodBuilder.returns(listenableFutureOf(spec.optionalType()));
-
-        switch (spec.valueKind()) {
-          case FUTURE: // return a ListenableFuture<Optional<ListenableFuture<T>>>
-          case PRODUCER: // return a ListenableFuture<Optional<Producer<T>>>
-            return getMethodBuilder
-                .addCode(
-                    "return $T.immediateFuture($L);",
-                    Futures.class,
-                    spec.optionalKind()
-                        .presentExpression(
-                            FrameworkType.PRODUCER_NODE.to(
-                                spec.valueKind(), CodeBlock.of("$N", delegateField))))
-                .build();
-
-          case INSTANCE: // return a ListenableFuture<Optional<T>>
-            return getMethodBuilder
-                .addCode(
-                    "return $L;",
-                    transformFutureToOptional(
-                        spec.optionalKind(),
-                        spec.typeVariable(),
-                        CodeBlock.of("$N.get()", delegateField)))
-                .build();
-
-          case PRODUCED: // return a ListenableFuture<Optional<Produced<T>>>
-            return getMethodBuilder
-                .addCode(
-                    "return $L;",
-                    transformFutureToOptional(
-                        spec.optionalKind(),
-                        spec.valueType(),
-                        CodeBlock.of(
-                            "$T.createFutureProduced($N.get())", Producers.class, delegateField)))
-                .build();
-
-          default:
-            throw new UnsupportedOperationException(
-                spec.factoryType() + " objects are not supported");
-        }
-    }
-    throw new AssertionError(spec.frameworkType());
-  }
-
-  /**
-   * An expression that uses {@link Futures#transform(ListenableFuture, Function, Executor)} to
-   * transform a {@code ListenableFuture<inputType>} into a {@code
-   * ListenableFuture<Optional<inputType>>}.
-   *
-   * @param inputFuture an expression of type {@code ListenableFuture<inputType>}
-   */
-  private static CodeBlock transformFutureToOptional(
-      OptionalKind optionalKind, TypeName inputType, CodeBlock inputFuture) {
-    return CodeBlock.of(
-        "$T.transform($L, $L, $T.directExecutor())",
-        Futures.class,
-        inputFuture,
-        anonymousClassBuilder("")
-            .addSuperinterface(
-                ParameterizedTypeName.get(
-                    ClassName.get(Function.class), inputType, optionalKind.of(inputType)))
-            .addMethod(
-                methodBuilder("apply")
-                    .addAnnotation(Override.class)
-                    .addModifiers(PUBLIC)
-                    .returns(optionalKind.of(inputType))
-                    .addParameter(inputType, "input")
-                    .addCode("return $L;", optionalKind.presentExpression(CodeBlock.of("input")))
-                    .build())
-            .build(),
-        MoreExecutors.class);
-  }
-}
diff --git a/java/dagger/internal/codegen/OptionalFactoryInstanceCreationExpression.java b/java/dagger/internal/codegen/OptionalFactoryInstanceCreationExpression.java
deleted file mode 100644
index ba9e25f..0000000
--- a/java/dagger/internal/codegen/OptionalFactoryInstanceCreationExpression.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-
-/**
- * A {@link FrameworkInstanceCreationExpression} for {@link dagger.model.BindingKind#OPTIONAL
- * optional bindings}.
- */
-final class OptionalFactoryInstanceCreationExpression
-    implements FrameworkInstanceCreationExpression {
-  private final OptionalFactories optionalFactories;
-  private final ContributionBinding binding;
-  private final ComponentImplementation componentImplementation;
-  private final ComponentBindingExpressions componentBindingExpressions;
-
-  OptionalFactoryInstanceCreationExpression(
-      OptionalFactories optionalFactories,
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions) {
-    this.optionalFactories = optionalFactories;
-    this.binding = binding;
-    this.componentImplementation = componentImplementation;
-    this.componentBindingExpressions = componentBindingExpressions;
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    return binding.dependencies().isEmpty()
-        ? optionalFactories.absentOptionalProvider(binding)
-        : optionalFactories.presentOptionalFactory(
-            binding,
-            componentBindingExpressions
-                .getDependencyExpression(
-                    bindingRequest(
-                        getOnlyElement(binding.dependencies()).key(), binding.frameworkType()),
-                    componentImplementation.name())
-                .codeBlock());
-  }
-
-  @Override
-  public boolean useInnerSwitchingProvider() {
-    // Share providers for empty optionals from OptionalFactories so we don't have numerous
-    // switch cases that all return Optional.empty().
-    return !binding.dependencies().isEmpty();
-  }
-}
diff --git a/java/dagger/internal/codegen/OptionalType.java b/java/dagger/internal/codegen/OptionalType.java
deleted file mode 100644
index 0fdbf68..0000000
--- a/java/dagger/internal/codegen/OptionalType.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.lang.model.element.Name;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * Information about an {@code Optional} {@link TypeMirror}.
- *
- * <p>{@link com.google.common.base.Optional} and {@link java.util.Optional} are supported.
- */
-@AutoValue
-abstract class OptionalType {
-
-  /** A variant of {@code Optional}. */
-  enum OptionalKind {
-    /** {@link com.google.common.base.Optional}. */
-    GUAVA_OPTIONAL(com.google.common.base.Optional.class, "absent"),
-
-    /** {@link java.util.Optional}. */
-    JDK_OPTIONAL(java.util.Optional.class, "empty"),
-    ;
-
-    private final Class<?> clazz;
-    private final String absentFactoryMethodName;
-
-    OptionalKind(Class<?> clazz, String absentFactoryMethodName) {
-      this.clazz = clazz;
-      this.absentFactoryMethodName = absentFactoryMethodName;
-    }
-
-    /** Returns {@code valueType} wrapped in the correct class. */
-    ParameterizedTypeName of(TypeName valueType) {
-      return ParameterizedTypeName.get(ClassName.get(clazz), valueType);
-    }
-
-    /** Returns an expression for the absent/empty value. */
-    CodeBlock absentValueExpression() {
-      return CodeBlock.of("$T.$L()", clazz, absentFactoryMethodName);
-    }
-
-    /**
-     * Returns an expression for the absent/empty value, parameterized with {@link #valueType()}.
-     */
-    CodeBlock parameterizedAbsentValueExpression(OptionalType optionalType) {
-      return CodeBlock.of("$T.<$T>$L()", clazz, optionalType.valueType(), absentFactoryMethodName);
-    }
-
-    /** Returns an expression for the present {@code value}. */
-    CodeBlock presentExpression(CodeBlock value) {
-      return CodeBlock.of("$T.of($L)", clazz, value);
-    }
-
-    /**
-     * Returns an expression for the present {@code value}, returning {@code Optional<Object>} no
-     * matter what type the value is.
-     */
-    CodeBlock presentObjectExpression(CodeBlock value) {
-      return CodeBlock.of("$T.<$T>of($L)", clazz, Object.class, value);
-    }
-  }
-
-  private static final TypeVisitor<Optional<OptionalKind>, Void> OPTIONAL_KIND =
-      new SimpleTypeVisitor8<Optional<OptionalKind>, Void>(Optional.empty()) {
-        @Override
-        public Optional<OptionalKind> visitDeclared(DeclaredType t, Void p) {
-          for (OptionalKind optionalKind : OptionalKind.values()) {
-            Name qualifiedName = MoreElements.asType(t.asElement()).getQualifiedName();
-            if (qualifiedName.contentEquals(optionalKind.clazz.getCanonicalName())) {
-              return Optional.of(optionalKind);
-            }
-          }
-          return Optional.empty();
-        }
-      };
-
-  /**
-   * The optional type itself, wrapped using {@link MoreTypes#equivalence()}.
-   *
-   * @deprecated Use {@link #declaredOptionalType()} instead.
-   */
-  @Deprecated
-  protected abstract Equivalence.Wrapper<DeclaredType> wrappedDeclaredOptionalType();
-
-  /** The optional type itself. */
-  @SuppressWarnings("deprecation")
-  DeclaredType declaredOptionalType() {
-    return wrappedDeclaredOptionalType().get();
-  }
-  
-  /** Which {@code Optional} type is used. */
-  OptionalKind kind() {
-    return declaredOptionalType().accept(OPTIONAL_KIND, null).get();
-  }
-
-  /** The value type. */
-  TypeMirror valueType() {
-    return declaredOptionalType().getTypeArguments().get(0);
-  }
-
-  /** Returns {@code true} if {@code type} is an {@code Optional} type. */
-  static boolean isOptional(TypeMirror type) {
-    return type.accept(OPTIONAL_KIND, null).isPresent();
-  }
-
-  /** Returns {@code true} if {@code key.type()} is an {@code Optional} type. */
-  static boolean isOptional(Key key) {
-    return isOptional(key.type());
-  }
-
-  /**
-   * Returns a {@link OptionalType} for {@code type}.
-   *
-   * @throws IllegalArgumentException if {@code type} is not an {@code Optional} type
-   */
-  static OptionalType from(TypeMirror type) {
-    checkArgument(isOptional(type), "%s must be an Optional", type);
-    return new AutoValue_OptionalType(MoreTypes.equivalence().wrap(MoreTypes.asDeclared(type)));
-  }
-
-  /**
-   * Returns a {@link OptionalType} for {@code key}'s {@link Key#type() type}.
-   *
-   * @throws IllegalArgumentException if {@code key.type()} is not an {@code Optional} type
-   */
-  static OptionalType from(Key key) {
-    return from(key.type());
-  }
-}
diff --git a/java/dagger/internal/codegen/Optionals.java b/java/dagger/internal/codegen/Optionals.java
deleted file mode 100644
index 1021c35..0000000
--- a/java/dagger/internal/codegen/Optionals.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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.checkNotNull;
-import static com.google.common.collect.Lists.asList;
-
-import java.util.Comparator;
-import java.util.Optional;
-import java.util.function.Function;
-
-/** Utilities for {@link Optional}s. */
-final class Optionals {
-  /**
-   * A {@link Comparator} that puts empty {@link Optional}s before present ones, and compares
-   * present {@link Optional}s by their values.
-   */
-  static <C extends Comparable<C>> Comparator<Optional<C>> optionalComparator() {
-    return Comparator.comparing((Optional<C> optional) -> optional.isPresent())
-        .thenComparing(Optional::get);
-  }
-
-  static <T> Comparator<Optional<T>> emptiesLast(Comparator<? super T> valueComparator) {
-    checkNotNull(valueComparator);
-    return Comparator.comparing(o -> o.orElse(null), Comparator.nullsLast(valueComparator));
-  }
-
-  /** Returns the first argument that is present, or empty if none are. */
-  @SafeVarargs
-  static <T> Optional<T> firstPresent(Optional<T> first, Optional<T> second, Optional<T>... rest) {
-    return asList(first, second, rest)
-        .stream()
-        .filter(Optional::isPresent)
-        .findFirst()
-        .orElse(Optional.empty());
-  }
-
-  /**
-   * Walks a chain of present optionals as defined by successive calls to {@code nextFunction},
-   * returning the value of the final optional that is present. The first optional in the chain is
-   * the result of {@code nextFunction(start)}.
-   */
-  static <T> T rootmostValue(T start, Function<T, Optional<T>> nextFunction) {
-    T current = start;
-    for (Optional<T> next = nextFunction.apply(start);
-        next.isPresent();
-        next = nextFunction.apply(current)) {
-      current = next.get();
-    }
-    return current;
-  }
-
-  private Optionals() {}
-}
diff --git a/java/dagger/internal/codegen/ParentComponent.java b/java/dagger/internal/codegen/ParentComponent.java
deleted file mode 100644
index 2d2b583..0000000
--- a/java/dagger/internal/codegen/ParentComponent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * A {@link Qualifier} for bindings that are associated with a component implementation's
- * parent component.
- */
-@Retention(RUNTIME)
-@Qualifier
-@interface ParentComponent {}
diff --git a/java/dagger/internal/codegen/PerComponentImplementation.java b/java/dagger/internal/codegen/PerComponentImplementation.java
deleted file mode 100644
index 5d4ba18..0000000
--- a/java/dagger/internal/codegen/PerComponentImplementation.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-/** A {@link Scope} that encompasses a single component implementation. */
-@Retention(RUNTIME)
-@Scope
-@interface PerComponentImplementation {}
diff --git a/java/dagger/internal/codegen/PerGeneratedFile.java b/java/dagger/internal/codegen/PerGeneratedFile.java
deleted file mode 100644
index c30e67a..0000000
--- a/java/dagger/internal/codegen/PerGeneratedFile.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-/**
- * A {@link Scope} that encompasses a top-level component implementation and any of its inner
- * descendant component implementations in the same generated file.
- */
-@Retention(RUNTIME)
-@Scope
-@interface PerGeneratedFile {}
diff --git a/java/dagger/internal/codegen/PrivateMethodBindingExpression.java b/java/dagger/internal/codegen/PrivateMethodBindingExpression.java
deleted file mode 100644
index 482c123..0000000
--- a/java/dagger/internal/codegen/PrivateMethodBindingExpression.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2017 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.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static dagger.internal.codegen.ComponentImplementation.MethodSpecKind.PRIVATE_METHOD;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-
-/**
- * A binding expression that wraps the dependency expressions in a private, no-arg method.
- *
- * <p>Dependents of this binding expression will just call the no-arg private method.
- */
-final class PrivateMethodBindingExpression extends MethodBindingExpression {
-  private final BindingRequest request;
-  private final ComponentImplementation componentImplementation;
-  private String methodName;
-
-  PrivateMethodBindingExpression(
-      BindingRequest request,
-      ResolvedBindings resolvedBindings,
-      MethodImplementationStrategy methodImplementationStrategy,
-      BindingExpression wrappedBindingExpression,
-      ComponentImplementation componentImplementation,
-      DaggerTypes types) {
-    super(
-        request,
-        resolvedBindings,
-        methodImplementationStrategy,
-        wrappedBindingExpression,
-        componentImplementation,
-        types);
-    this.request = checkNotNull(request);
-    this.componentImplementation = checkNotNull(componentImplementation);
-  }
-
-  @Override
-  protected void addMethod() {
-    if (methodName == null) {
-      // Have to set methodName field before implementing the method in order to handle recursion.
-      methodName = componentImplementation.getUniqueMethodName(request);
-      // TODO(user): Fix the order that these generated methods are written to the component.
-      componentImplementation.addMethod(
-          PRIVATE_METHOD,
-          methodBuilder(methodName)
-              .addModifiers(PRIVATE)
-              .returns(TypeName.get(returnType()))
-              .addCode(methodBody())
-              .build());
-    }
-  }
-
-  @Override
-  protected String methodName() {
-    checkState(methodName != null, "addMethod() must be called before methodName()");
-    return methodName;
-  }
-}
diff --git a/java/dagger/internal/codegen/ProcessingEnvironmentCompilerOptions.java b/java/dagger/internal/codegen/ProcessingEnvironmentCompilerOptions.java
deleted file mode 100644
index cf2475d..0000000
--- a/java/dagger/internal/codegen/ProcessingEnvironmentCompilerOptions.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2019 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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Sets.immutableEnumSet;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.FeatureStatus.DISABLED;
-import static dagger.internal.codegen.FeatureStatus.ENABLED;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.EMIT_MODIFIABLE_METADATA_ANNOTATIONS;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.EXPERIMENTAL_AHEAD_OF_TIME_SUBCOMPONENTS;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.EXPERIMENTAL_ANDROID_MODE;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.FAST_INIT;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.FLOATING_BINDS_METHODS;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.FORCE_USE_SERIALIZED_COMPONENT_IMPLEMENTATIONS;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.FORMAT_GENERATED_SOURCE;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.WARN_IF_INJECTION_FACTORY_NOT_GENERATED_UPSTREAM;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Feature.WRITE_PRODUCER_NAME_IN_TOKEN;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.KeyOnlyOption.HEADER_COMPILATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.KeyOnlyOption.USE_GRADLE_INCREMENTAL_PROCESSING;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.DISABLE_INTER_COMPONENT_SCOPE_VALIDATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.EXPLICIT_BINDING_CONFLICTS_WITH_INJECT;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.FULL_BINDING_GRAPH_VALIDATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.MODULE_HAS_DIFFERENT_SCOPES_VALIDATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.NULLABLE_VALIDATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.PRIVATE_MEMBER_VALIDATION;
-import static dagger.internal.codegen.ProcessingEnvironmentCompilerOptions.Validation.STATIC_MEMBER_VALIDATION;
-import static dagger.internal.codegen.ValidationType.ERROR;
-import static dagger.internal.codegen.ValidationType.NONE;
-import static dagger.internal.codegen.ValidationType.WARNING;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Stream.concat;
-
-import com.google.common.base.Ascii;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import dagger.producers.Produces;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-
-final class ProcessingEnvironmentCompilerOptions extends CompilerOptions {
-  /** Returns a valid {@link CompilerOptions} parsed from the processing environment. */
-  static CompilerOptions create(ProcessingEnvironment processingEnvironment) {
-    return new ProcessingEnvironmentCompilerOptions(processingEnvironment).checkValid();
-  }
-
-  private final ProcessingEnvironment processingEnvironment;
-  private final Map<EnumOption<?>, Object> enumOptions = new HashMap<>();
-  private final Map<EnumOption<?>, ImmutableMap<String, ? extends Enum<?>>> allCommandLineOptions =
-      new HashMap<>();
-
-  private ProcessingEnvironmentCompilerOptions(ProcessingEnvironment processingEnvironment) {
-    this.processingEnvironment = processingEnvironment;
-  }
-
-  @Override
-  boolean usesProducers() {
-    return processingEnvironment.getElementUtils().getTypeElement(Produces.class.getCanonicalName())
-        != null;
-  }
-
-  @Override
-  boolean headerCompilation() {
-    return isEnabled(HEADER_COMPILATION);
-  }
-
-  @Override
-  boolean fastInit() {
-    return isEnabled(FAST_INIT);
-  }
-
-  @Override
-  boolean formatGeneratedSource() {
-    return isEnabled(FORMAT_GENERATED_SOURCE);
-  }
-
-  @Override
-  boolean writeProducerNameInToken() {
-    return isEnabled(WRITE_PRODUCER_NAME_IN_TOKEN);
-  }
-
-  @Override
-  Diagnostic.Kind nullableValidationKind() {
-    return diagnosticKind(NULLABLE_VALIDATION);
-  }
-
-  @Override
-  Diagnostic.Kind privateMemberValidationKind() {
-    return diagnosticKind(PRIVATE_MEMBER_VALIDATION);
-  }
-
-  @Override
-  Diagnostic.Kind staticMemberValidationKind() {
-    return diagnosticKind(STATIC_MEMBER_VALIDATION);
-  }
-
-  @Override
-  boolean ignorePrivateAndStaticInjectionForComponent() {
-    return isEnabled(IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT);
-  }
-
-  @Override
-  ValidationType scopeCycleValidationType() {
-    return parseOption(DISABLE_INTER_COMPONENT_SCOPE_VALIDATION);
-  }
-
-  @Override
-  boolean warnIfInjectionFactoryNotGeneratedUpstream() {
-    return isEnabled(WARN_IF_INJECTION_FACTORY_NOT_GENERATED_UPSTREAM);
-  }
-
-  @Override
-  boolean aheadOfTimeSubcomponents() {
-    return isEnabled(EXPERIMENTAL_AHEAD_OF_TIME_SUBCOMPONENTS);
-  }
-
-  @Override
-  boolean forceUseSerializedComponentImplementations() {
-    return isEnabled(FORCE_USE_SERIALIZED_COMPONENT_IMPLEMENTATIONS);
-  }
-
-  @Override
-  boolean emitModifiableMetadataAnnotations() {
-    return isEnabled(EMIT_MODIFIABLE_METADATA_ANNOTATIONS);
-  }
-
-  @Override
-  boolean useGradleIncrementalProcessing() {
-    return isEnabled(USE_GRADLE_INCREMENTAL_PROCESSING);
-  }
-
-  @Override
-  ValidationType fullBindingGraphValidationType(TypeElement element) {
-    return fullBindingGraphValidationType();
-  }
-
-  private ValidationType fullBindingGraphValidationType() {
-    return parseOption(FULL_BINDING_GRAPH_VALIDATION);
-  }
-
-  @Override
-  Diagnostic.Kind moduleHasDifferentScopesDiagnosticKind() {
-    return diagnosticKind(MODULE_HAS_DIFFERENT_SCOPES_VALIDATION);
-  }
-
-  @Override
-  ValidationType explicitBindingConflictsWithInjectValidationType() {
-    return parseOption(EXPLICIT_BINDING_CONFLICTS_WITH_INJECT);
-  }
-
-  private boolean isEnabled(KeyOnlyOption keyOnlyOption) {
-    return processingEnvironment.getOptions().containsKey(keyOnlyOption.toString());
-  }
-
-  private boolean isEnabled(Feature feature) {
-    return parseOption(feature).equals(ENABLED);
-  }
-
-  private Diagnostic.Kind diagnosticKind(Validation validation) {
-    return parseOption(validation).diagnosticKind().get();
-  }
-
-  @SuppressWarnings("CheckReturnValue")
-  private ProcessingEnvironmentCompilerOptions checkValid() {
-    for (KeyOnlyOption keyOnlyOption : KeyOnlyOption.values()) {
-      isEnabled(keyOnlyOption);
-    }
-    for (Feature feature : Feature.values()) {
-      parseOption(feature);
-    }
-    for (Validation validation : Validation.values()) {
-      parseOption(validation);
-    }
-    noLongerRecognized(EXPERIMENTAL_ANDROID_MODE);
-    noLongerRecognized(FLOATING_BINDS_METHODS);
-    return this;
-  }
-
-  private void noLongerRecognized(CommandLineOption commandLineOption) {
-    if (processingEnvironment.getOptions().containsKey(commandLineOption.toString())) {
-      processingEnvironment
-          .getMessager()
-          .printMessage(
-              Diagnostic.Kind.WARNING, commandLineOption + " is no longer recognized by Dagger");
-    }
-  }
-
-  private interface CommandLineOption {
-    /** The key of the option (appears after "-A"). */
-    @Override
-    String toString();
-
-    /**
-     * Returns all aliases besides {@link #toString()}, such as old names for an option, in order of
-     * precedence.
-     */
-    default ImmutableList<String> aliases() {
-      return ImmutableList.of();
-    }
-
-    /** All the command-line names for this option, in order of precedence. */
-    default Stream<String> allNames() {
-      return concat(Stream.of(toString()), aliases().stream());
-    }
-  }
-
-  /** An option that can be set on the command line. */
-  private interface EnumOption<E extends Enum<E>> extends CommandLineOption {
-    /** The default value for this option. */
-    E defaultValue();
-
-    /** The valid values for this option. */
-    Set<E> validValues();
-  }
-
-  enum KeyOnlyOption implements CommandLineOption {
-    HEADER_COMPILATION {
-      @Override
-      public String toString() {
-        return "experimental_turbine_hjar";
-      }
-    },
-
-    USE_GRADLE_INCREMENTAL_PROCESSING {
-      @Override
-      public String toString() {
-        return "dagger.gradle.incremental";
-      }
-    },
-  }
-
-  /**
-   * A feature that can be enabled or disabled on the command line by setting {@code -Akey=ENABLED}
-   * or {@code -Akey=DISABLED}.
-   */
-  enum Feature implements EnumOption<FeatureStatus> {
-    FAST_INIT,
-
-    EXPERIMENTAL_ANDROID_MODE,
-
-    FORMAT_GENERATED_SOURCE,
-
-    WRITE_PRODUCER_NAME_IN_TOKEN,
-
-    WARN_IF_INJECTION_FACTORY_NOT_GENERATED_UPSTREAM,
-
-    IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT,
-
-    EXPERIMENTAL_AHEAD_OF_TIME_SUBCOMPONENTS,
-
-    FORCE_USE_SERIALIZED_COMPONENT_IMPLEMENTATIONS,
-
-    EMIT_MODIFIABLE_METADATA_ANNOTATIONS(ENABLED),
-
-    FLOATING_BINDS_METHODS,
-    ;
-
-    final FeatureStatus defaultValue;
-
-    Feature() {
-      this(DISABLED);
-    }
-
-    Feature(FeatureStatus defaultValue) {
-      this.defaultValue = defaultValue;
-    }
-
-    @Override
-    public FeatureStatus defaultValue() {
-      return defaultValue;
-    }
-
-    @Override
-    public Set<FeatureStatus> validValues() {
-      return EnumSet.allOf(FeatureStatus.class);
-    }
-
-    @Override
-    public String toString() {
-      return optionName(this);
-    }
-  }
-
-  /** The diagnostic kind or validation type for a kind of validation. */
-  enum Validation implements EnumOption<ValidationType> {
-    DISABLE_INTER_COMPONENT_SCOPE_VALIDATION(),
-
-    NULLABLE_VALIDATION(ERROR, WARNING),
-
-    PRIVATE_MEMBER_VALIDATION(ERROR, WARNING),
-
-    STATIC_MEMBER_VALIDATION(ERROR, WARNING),
-
-    /** Whether to validate full binding graphs for components, subcomponents, and modules. */
-    FULL_BINDING_GRAPH_VALIDATION(NONE, ERROR, WARNING) {
-      @Override
-      public ImmutableList<String> aliases() {
-        return ImmutableList.of("dagger.moduleBindingValidation");
-      }
-    },
-
-    /**
-     * How to report conflicting scoped bindings when validating partial binding graphs associated
-     * with modules.
-     */
-    MODULE_HAS_DIFFERENT_SCOPES_VALIDATION(ERROR, WARNING),
-
-    /**
-     * How to report that an explicit binding in a subcomponent conflicts with an {@code @Inject}
-     * constructor used in an ancestor component.
-     */
-    EXPLICIT_BINDING_CONFLICTS_WITH_INJECT(WARNING, ERROR, NONE),
-    ;
-
-    final ValidationType defaultType;
-    final ImmutableSet<ValidationType> validTypes;
-
-    Validation() {
-      this(ERROR, WARNING, NONE);
-    }
-
-    Validation(ValidationType defaultType, ValidationType... moreValidTypes) {
-      this.defaultType = defaultType;
-      this.validTypes = immutableEnumSet(defaultType, moreValidTypes);
-    }
-
-    @Override
-    public ValidationType defaultValue() {
-      return defaultType;
-    }
-
-    @Override
-    public Set<ValidationType> validValues() {
-      return validTypes;
-    }
-
-    @Override
-    public String toString() {
-      return optionName(this);
-    }
-  }
-
-  private static String optionName(Enum<? extends EnumOption<?>> option) {
-    return "dagger." + UPPER_UNDERSCORE.to(LOWER_CAMEL, option.name());
-  }
-
-  /** The supported command-line options. */
-  static ImmutableSet<String> supportedOptions() {
-    // need explicit type parameter to avoid a runtime stream error
-    return Stream.<CommandLineOption[]>of(
-            KeyOnlyOption.values(), Feature.values(), Validation.values())
-        .flatMap(Arrays::stream)
-        .flatMap(CommandLineOption::allNames)
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the value for the option as set on the command line by any name, or the default value
-   * if not set.
-   *
-   * <p>If more than one name is used to set the value, but all names specify the same value,
-   * reports a warning and returns that value.
-   *
-   * <p>If more than one name is used to set the value, and not all names specify the same value,
-   * reports an error and returns the default value.
-   */
-  private <T extends Enum<T>> T parseOption(EnumOption<T> option) {
-    @SuppressWarnings("unchecked") // we only put covariant values into the map
-    T value = (T) enumOptions.computeIfAbsent(option, this::parseOptionUncached);
-    return value;
-  }
-
-  private <T extends Enum<T>> T parseOptionUncached(EnumOption<T> option) {
-    ImmutableMap<String, T> values = parseOptionWithAllNames(option);
-
-    // If no value is specified, return the default value.
-    if (values.isEmpty()) {
-      return option.defaultValue();
-    }
-
-    // If all names have the same value, return that.
-    if (values.asMultimap().inverse().keySet().size() == 1) {
-      // Warn if an option was set with more than one name. That would be an error if the values
-      // differed.
-      if (values.size() > 1) {
-        reportUseOfDifferentNamesForOption(Diagnostic.Kind.WARNING, option, values.keySet());
-      }
-      return values.values().asList().get(0);
-    }
-
-    // If different names have different values, report an error and return the default
-    // value.
-    reportUseOfDifferentNamesForOption(Diagnostic.Kind.ERROR, option, values.keySet());
-    return option.defaultValue();
-  }
-
-  private void reportUseOfDifferentNamesForOption(
-      Diagnostic.Kind diagnosticKind, EnumOption<?> option, ImmutableSet<String> usedNames) {
-    processingEnvironment
-        .getMessager()
-        .printMessage(
-            diagnosticKind,
-            String.format(
-                "Only one of the equivalent options (%s) should be used; prefer -A%s",
-                usedNames.stream().map(name -> "-A" + name).collect(joining(", ")), option));
-  }
-
-  private <T extends Enum<T>> ImmutableMap<String, T> parseOptionWithAllNames(
-      EnumOption<T> option) {
-    @SuppressWarnings("unchecked") // map is covariant
-    ImmutableMap<String, T> aliasValues =
-        (ImmutableMap<String, T>)
-            allCommandLineOptions.computeIfAbsent(option, this::parseOptionWithAllNamesUncached);
-    return aliasValues;
-  }
-
-  private <T extends Enum<T>> ImmutableMap<String, T> parseOptionWithAllNamesUncached(
-      EnumOption<T> option) {
-    ImmutableMap.Builder<String, T> values = ImmutableMap.builder();
-    getUsedNames(option)
-        .forEach(
-            name -> parseOptionWithName(option, name).ifPresent(value -> values.put(name, value)));
-    return values.build();
-  }
-
-  private <T extends Enum<T>> Optional<T> parseOptionWithName(EnumOption<T> option, String key) {
-    checkArgument(processingEnvironment.getOptions().containsKey(key), "key %s not found", key);
-    String stringValue = processingEnvironment.getOptions().get(key);
-    if (stringValue == null) {
-      processingEnvironment
-          .getMessager()
-          .printMessage(Diagnostic.Kind.ERROR, "Processor option -A" + key + " needs a value");
-    } else {
-      try {
-        T value =
-            Enum.valueOf(option.defaultValue().getDeclaringClass(), Ascii.toUpperCase(stringValue));
-        if (option.validValues().contains(value)) {
-          return Optional.of(value);
-        }
-      } catch (IllegalArgumentException e) {
-        // handled below
-      }
-      processingEnvironment
-          .getMessager()
-          .printMessage(
-              Diagnostic.Kind.ERROR,
-              String.format(
-                  "Processor option -A%s may only have the values %s "
-                      + "(case insensitive), found: %s",
-                  key, option.validValues(), stringValue));
-    }
-    return Optional.empty();
-  }
-
-  private Stream<String> getUsedNames(CommandLineOption option) {
-    return option.allNames().filter(name -> processingEnvironment.getOptions().containsKey(name));
-  }
-}
diff --git a/java/dagger/internal/codegen/ProcessingEnvironmentModule.java b/java/dagger/internal/codegen/ProcessingEnvironmentModule.java
deleted file mode 100644
index 1730574..0000000
--- a/java/dagger/internal/codegen/ProcessingEnvironmentModule.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-
-import com.google.googlejavaformat.java.filer.FormattingFiler;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Map;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.util.Types;
-
-/** Bindings that depend on the {@link ProcessingEnvironment}. */
-@Module
-final class ProcessingEnvironmentModule {
-
-  private final ProcessingEnvironment processingEnvironment;
-
-  ProcessingEnvironmentModule(ProcessingEnvironment processingEnvironment) {
-    this.processingEnvironment = checkNotNull(processingEnvironment);
-  }
-
-  @Provides
-  @ProcessingOptions
-  Map<String, String> processingOptions() {
-    return processingEnvironment.getOptions();
-  }
-
-  @Provides
-  Messager messager() {
-    return processingEnvironment.getMessager();
-  }
-
-  @Provides
-  Filer filer(CompilerOptions compilerOptions) {
-    if (compilerOptions.headerCompilation() || !compilerOptions.formatGeneratedSource()) {
-      return processingEnvironment.getFiler();
-    } else {
-      return new FormattingFiler(processingEnvironment.getFiler());
-    }
-  }
-
-  @Provides
-  Types types() {
-    return processingEnvironment.getTypeUtils();
-  }
-
-  @Provides
-  SourceVersion sourceVersion() {
-    return processingEnvironment.getSourceVersion();
-  }
-
-  @Provides
-  DaggerElements daggerElements() {
-    return new DaggerElements(processingEnvironment);
-  }
-
-  @Provides
-  @Reusable // to avoid parsing options more than once
-  CompilerOptions compilerOptions() {
-    return ProcessingEnvironmentCompilerOptions.create(processingEnvironment);
-  }
-
-  @Provides
-  Optional<DaggerStatisticsRecorder> daggerStatisticsRecorder() {
-    return Optional.empty();
-  }
-}
diff --git a/java/dagger/internal/codegen/ProcessingOptions.java b/java/dagger/internal/codegen/ProcessingOptions.java
deleted file mode 100644
index 105452a..0000000
--- a/java/dagger/internal/codegen/ProcessingOptions.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * A qualifier for the {@link javax.annotation.processing.ProcessingEnvironment#getOptions()
- * processing options} passed to the current invocation of {@code javac}.
- */
-@Retention(RUNTIME)
-@Qualifier
-@interface ProcessingOptions {}
diff --git a/java/dagger/internal/codegen/ProcessingRoundCacheModule.java b/java/dagger/internal/codegen/ProcessingRoundCacheModule.java
deleted file mode 100644
index b56cc30..0000000
--- a/java/dagger/internal/codegen/ProcessingRoundCacheModule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 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 dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.IntoSet;
-
-/**
- * Binding contributions to a set of {@link ClearableCache}s that will be cleared at the end of each
- * processing round.
- */
-@Module
-interface ProcessingRoundCacheModule {
-  @Binds
-  @IntoSet
-  ClearableCache moduleDescriptorFactory(ModuleDescriptor.Factory cache);
-
-  @Binds
-  @IntoSet
-  ClearableCache bindingGraphFactory(BindingGraphFactory cache);
-
-  @Binds
-  @IntoSet
-  ClearableCache componentImplementationFactory(ComponentImplementationFactory cache);
-}
diff --git a/java/dagger/internal/codegen/ProducerCreationExpression.java b/java/dagger/internal/codegen/ProducerCreationExpression.java
deleted file mode 100644
index 1dd7a1c..0000000
--- a/java/dagger/internal/codegen/ProducerCreationExpression.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-
-/**
- * A {@link dagger.producers.Producer} creation expression for a {@link
- * dagger.producers.Produces @Produces}-annotated module method.
- */
-// TODO(dpb): Resolve with InjectionOrProvisionProviderCreationExpression.
-final class ProducerCreationExpression implements FrameworkInstanceCreationExpression {
-
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final ContributionBinding binding;
-
-  ProducerCreationExpression(
-      ContributionBinding binding, ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    return CodeBlock.of(
-        "$T.create($L)",
-        generatedClassNameForBinding(binding),
-        componentBindingExpressions.getCreateMethodArgumentsCodeBlock(binding));
-  }
-}
diff --git a/java/dagger/internal/codegen/ProducerEntryPointView.java b/java/dagger/internal/codegen/ProducerEntryPointView.java
deleted file mode 100644
index 87b5a4a..0000000
--- a/java/dagger/internal/codegen/ProducerEntryPointView.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.ComponentImplementation.FieldSpecKind.FRAMEWORK_FIELD;
-import static javax.lang.model.element.Modifier.PRIVATE;
-
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.RequestKind;
-import dagger.producers.Producer;
-import dagger.producers.internal.CancellationListener;
-import dagger.producers.internal.Producers;
-import java.util.Optional;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A factory of {@linkplain Producers#entryPointViewOf(Producer, CancellationListener) entry point
- * views} of {@link Producer}s.
- */
-final class ProducerEntryPointView {
-  private final DaggerTypes types;
-
-  ProducerEntryPointView(DaggerTypes types) {
-    this.types = types;
-  }
-
-  /**
-   * Returns an expression for an {@linkplain Producers#entryPointViewOf(Producer,
-   * CancellationListener) entry point view} of a producer if the component method returns a {@link
-   * Producer} or {@link com.google.common.util.concurrent.ListenableFuture}.
-   *
-   * <p>This is intended to be a replacement implementation for {@link
-   * BindingExpression#getDependencyExpressionForComponentMethod(ComponentMethodDescriptor,
-   * ComponentImplementation)}, and in cases where {@link Optional#empty()} is returned, callers
-   * should call {@code super.getDependencyExpressionForComponentMethod()}.
-   */
-  Optional<Expression> getProducerEntryPointField(
-      BindingExpression producerExpression,
-      ComponentMethodDescriptor componentMethod,
-      ComponentImplementation component) {
-    if (component.componentDescriptor().isProduction()
-        && (componentMethod.dependencyRequest().get().kind().equals(RequestKind.FUTURE)
-            || componentMethod.dependencyRequest().get().kind().equals(RequestKind.PRODUCER))) {
-      return Optional.of(
-          Expression.create(
-              fieldType(componentMethod),
-              "$N",
-              createField(producerExpression, componentMethod, component)));
-    } else {
-      // If the component isn't a production component, it won't implement CancellationListener and
-      // as such we can't create an entry point. But this binding must also just be a Producer from
-      // Provider anyway in that case, so there shouldn't be an issue.
-      // TODO(b/116855531): Is it really intended that a non-production component can have Producer
-      // entry points?
-      return Optional.empty();
-    }
-  }
-
-  private FieldSpec createField(
-      BindingExpression producerExpression,
-      ComponentMethodDescriptor componentMethod,
-      ComponentImplementation component) {
-    // TODO(cgdecker): Use a FrameworkFieldInitializer for this?
-    // Though I don't think we need the once-only behavior of that, since I think
-    // getComponentMethodImplementation will only be called once anyway
-    String methodName = componentMethod.methodElement().getSimpleName().toString();
-    FieldSpec field =
-        FieldSpec.builder(
-                TypeName.get(fieldType(componentMethod)),
-                component.getUniqueFieldName(methodName + "EntryPoint"),
-                PRIVATE)
-            .build();
-    component.addField(FRAMEWORK_FIELD, field);
-
-    CodeBlock fieldInitialization =
-        CodeBlock.of(
-            "this.$N = $T.entryPointViewOf($L, this);",
-            field,
-            Producers.class,
-            producerExpression.getDependencyExpression(component.name()).codeBlock());
-    component.addInitialization(fieldInitialization);
-
-    return field;
-  }
-
-  // TODO(cgdecker): Can we use producerExpression.getDependencyExpression().type() instead of
-  // needing to (re)compute this?
-  private TypeMirror fieldType(ComponentMethodDescriptor componentMethod) {
-    return types.wrapType(componentMethod.dependencyRequest().get().key().type(), Producer.class);
-  }
-}
diff --git a/java/dagger/internal/codegen/ProducerFactoryGenerator.java b/java/dagger/internal/codegen/ProducerFactoryGenerator.java
deleted file mode 100644
index 3f2bef4..0000000
--- a/java/dagger/internal/codegen/ProducerFactoryGenerator.java
+++ /dev/null
@@ -1,553 +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.Verify.verifyNotNull;
-import static com.squareup.javapoet.ClassName.OBJECT;
-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.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.GwtCompatibility.gwtIncompatibleAnnotation;
-import static dagger.internal.codegen.SourceFiles.bindingTypeElementTypeVariableNames;
-import static dagger.internal.codegen.SourceFiles.generateBindingFieldsForDependencies;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-import static dagger.internal.codegen.SourceFiles.parameterizedGeneratedTypeNameForBinding;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.FUTURES;
-import static dagger.internal.codegen.javapoet.TypeNames.PRODUCERS;
-import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER_TOKEN;
-import static dagger.internal.codegen.javapoet.TypeNames.VOID_CLASS;
-import static dagger.internal.codegen.javapoet.TypeNames.listOf;
-import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf;
-import static dagger.internal.codegen.javapoet.TypeNames.producedOf;
-import static java.util.stream.Collectors.joining;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.PROTECTED;
-import static javax.lang.model.element.Modifier.PUBLIC;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.javapoet.AnnotationSpecs;
-import dagger.internal.codegen.javapoet.TypeNames;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import dagger.producers.Producer;
-import dagger.producers.internal.AbstractProducesMethodProducer;
-import dagger.producers.internal.Producers;
-import java.util.Map;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Generates {@link Producer} implementations from {@link ProductionBinding} instances.
- */
-final class ProducerFactoryGenerator extends SourceFileGenerator<ProductionBinding> {
-  private final CompilerOptions compilerOptions;
-  private final KeyFactory keyFactory;
-
-  @Inject
-  ProducerFactoryGenerator(
-      Filer filer,
-      DaggerElements elements,
-      SourceVersion sourceVersion,
-      CompilerOptions compilerOptions,
-      KeyFactory keyFactory) {
-    super(filer, elements, sourceVersion);
-    this.compilerOptions = compilerOptions;
-    this.keyFactory = keyFactory;
-  }
-
-  @Override
-  ClassName nameGeneratedType(ProductionBinding binding) {
-    return generatedClassNameForBinding(binding);
-  }
-
-  @Override
-  Element originatingElement(ProductionBinding binding) {
-    // we only create factories for bindings that have a binding element
-    return binding.bindingElement().get();
-  }
-
-  @Override
-  Optional<TypeSpec.Builder> write(ClassName generatedTypeName, ProductionBinding binding) {
-    // We don't want to write out resolved bindings -- we want to write out the generic version.
-    checkArgument(!binding.unresolved().isPresent());
-    checkArgument(binding.bindingElement().isPresent());
-
-    TypeName providedTypeName = TypeName.get(binding.contributedType());
-    TypeName futureTypeName = listenableFutureOf(providedTypeName);
-
-    TypeSpec.Builder factoryBuilder =
-        classBuilder(generatedTypeName)
-            .addAnnotation(
-                // TODO(beder): examine if we can remove this or prevent subtypes of Future from
-                // being produced
-                AnnotationSpec.builder(SuppressWarnings.class)
-                    .addMember("value", "$S", "FutureReturnValueIgnored")
-                    .build())
-            .addModifiers(PUBLIC, FINAL)
-            .addTypeVariables(bindingTypeElementTypeVariableNames(binding));
-
-    UniqueNameSet uniqueFieldNames = new UniqueNameSet();
-    ImmutableMap.Builder<Key, FieldSpec> fieldsBuilder = ImmutableMap.builder();
-
-    MethodSpec.Builder constructorBuilder = constructorBuilder().addModifiers(PRIVATE);
-
-    Optional<FieldSpec> moduleField =
-        binding.requiresModuleInstance()
-            ? Optional.of(
-                addFieldAndConstructorParameter(
-                    factoryBuilder,
-                    constructorBuilder,
-                    uniqueFieldNames.getUniqueName("module"),
-                    TypeName.get(binding.bindingTypeElement().get().asType())))
-            : Optional.empty();
-
-    String[] executorParameterName = new String[1];
-    String[] monitorParameterName = new String[1];
-    Map<Key, FrameworkField> bindingFieldsForDependencies =
-        generateBindingFieldsForDependencies(binding);
-    bindingFieldsForDependencies.forEach(
-        (key, bindingField) -> {
-          String fieldName = uniqueFieldNames.getUniqueName(bindingField.name());
-          if (key.equals(keyFactory.forProductionImplementationExecutor())) {
-            executorParameterName[0] = fieldName;
-            constructorBuilder.addParameter(bindingField.type(), executorParameterName[0]);
-          } else if (key.equals(keyFactory.forProductionComponentMonitor())) {
-            monitorParameterName[0] = fieldName;
-            constructorBuilder.addParameter(bindingField.type(), monitorParameterName[0]);
-          } else {
-            FieldSpec field =
-                addFieldAndConstructorParameter(
-                    factoryBuilder, constructorBuilder, fieldName, bindingField.type());
-            fieldsBuilder.put(key, field);
-          }
-        });
-    ImmutableMap<Key, FieldSpec> fields = fieldsBuilder.build();
-
-    constructorBuilder.addStatement(
-        "super($N, $L, $N)",
-        verifyNotNull(monitorParameterName[0]),
-        producerTokenConstruction(generatedTypeName, binding),
-        verifyNotNull(executorParameterName[0]));
-
-    if (binding.requiresModuleInstance()) {
-      assignField(constructorBuilder, moduleField.get(), null);
-    }
-
-    fields.forEach(
-        (key, field) -> {
-          ParameterizedTypeName type = bindingFieldsForDependencies.get(key).type();
-          assignField(constructorBuilder, field, type);
-        });
-
-    MethodSpec.Builder collectDependenciesBuilder =
-        methodBuilder("collectDependencies")
-            .addAnnotation(Override.class)
-            .addModifiers(PROTECTED);
-
-    ImmutableList<DependencyRequest> asyncDependencies = asyncDependencies(binding);
-    for (DependencyRequest dependency : asyncDependencies) {
-      TypeName futureType = listenableFutureOf(asyncDependencyType(dependency));
-      CodeBlock futureAccess = CodeBlock.of("$N.get()", fields.get(dependency.key()));
-      collectDependenciesBuilder.addStatement(
-          "$T $L = $L",
-          futureType,
-          dependencyFutureName(dependency),
-          dependency.kind().equals(RequestKind.PRODUCED)
-              ? CodeBlock.of("$T.createFutureProduced($L)", PRODUCERS, futureAccess)
-              : futureAccess);
-    }
-    FutureTransform futureTransform = FutureTransform.create(fields, binding, asyncDependencies);
-
-    collectDependenciesBuilder
-        .returns(listenableFutureOf(futureTransform.applyArgType()))
-        .addStatement("return $L", futureTransform.futureCodeBlock());
-
-    MethodSpec.Builder callProducesMethod =
-        methodBuilder("callProducesMethod")
-            .returns(futureTypeName)
-            .addAnnotation(Override.class)
-            .addModifiers(PUBLIC)
-            .addParameter(futureTransform.applyArgType(), futureTransform.applyArgName())
-            .addExceptions(getThrownTypeNames(binding.thrownTypes()))
-            .addCode(
-                getInvocationCodeBlock(
-                    binding, providedTypeName, futureTransform.parameterCodeBlocks()));
-    if (futureTransform.hasUncheckedCast()) {
-      callProducesMethod.addAnnotation(AnnotationSpecs.suppressWarnings(UNCHECKED));
-    }
-
-    MethodSpec constructor = constructorBuilder.build();
-    factoryBuilder
-        .superclass(
-            ParameterizedTypeName.get(
-                ClassName.get(AbstractProducesMethodProducer.class),
-                futureTransform.applyArgType(),
-                providedTypeName))
-        .addMethod(constructor)
-        .addMethod(staticFactoryMethod(binding, constructor))
-        .addMethod(collectDependenciesBuilder.build())
-        .addMethod(callProducesMethod.build());
-
-    gwtIncompatibleAnnotation(binding).ifPresent(factoryBuilder::addAnnotation);
-
-    // TODO(gak): write a sensible toString
-    return Optional.of(factoryBuilder);
-  }
-
-  private MethodSpec staticFactoryMethod(ProductionBinding binding, MethodSpec constructor) {
-    return MethodSpec.methodBuilder("create")
-        .addModifiers(PUBLIC, STATIC)
-        .returns(parameterizedGeneratedTypeNameForBinding(binding))
-        .addTypeVariables(bindingTypeElementTypeVariableNames(binding))
-        .addParameters(constructor.parameters)
-        .addStatement(
-            "return new $T($L)",
-            parameterizedGeneratedTypeNameForBinding(binding),
-            constructor.parameters.stream()
-                .map(p -> CodeBlock.of("$N", p.name))
-                .collect(toParametersCodeBlock()))
-        .build();
-  }
-
-  // TODO(ronshapiro): consolidate versions of these
-  private static FieldSpec addFieldAndConstructorParameter(
-      TypeSpec.Builder typeBuilder,
-      MethodSpec.Builder constructorBuilder,
-      String variableName,
-      TypeName variableType) {
-    FieldSpec field = FieldSpec.builder(variableType, variableName, PRIVATE, FINAL).build();
-    typeBuilder.addField(field);
-    constructorBuilder.addParameter(field.type, field.name);
-    return field;
-  }
-
-  private static void assignField(
-      MethodSpec.Builder constructorBuilder, FieldSpec field, ParameterizedTypeName type) {
-    if (type != null && type.rawType.equals(TypeNames.PRODUCER)) {
-      constructorBuilder.addStatement(
-          "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, Producers.class);
-    } else {
-      constructorBuilder.addStatement("this.$1N = $1N", field);
-    }
-  }
-
-  /** Returns a list of dependencies that are generated asynchronously. */
-  private static ImmutableList<DependencyRequest> asyncDependencies(Binding binding) {
-    final ImmutableMap<DependencyRequest, FrameworkDependency> frameworkDependencies =
-        binding.dependenciesToFrameworkDependenciesMap();
-    return FluentIterable.from(binding.dependencies())
-        .filter(
-            dependency ->
-                isAsyncDependency(dependency)
-                    && frameworkDependencies
-                        .get(dependency)
-                        .frameworkClass()
-                        .equals(Producer.class))
-        .toList();
-  }
-
-  private CodeBlock producerTokenConstruction(
-      ClassName generatedTypeName, ProductionBinding binding) {
-    CodeBlock producerTokenArgs =
-        compilerOptions.writeProducerNameInToken()
-            ? CodeBlock.of(
-                "$S",
-                String.format(
-                    "%s#%s",
-                    ClassName.get(binding.bindingTypeElement().get()),
-                    binding.bindingElement().get().getSimpleName()))
-            : CodeBlock.of("$T.class", generatedTypeName);
-    return CodeBlock.of("$T.create($L)", PRODUCER_TOKEN, producerTokenArgs);
-  }
-
-  /** Returns a name of the variable representing this dependency's future. */
-  private static String dependencyFutureName(DependencyRequest dependency) {
-    return dependency.requestElement().get().getSimpleName() + "Future";
-  }
-
-  /** Represents the transformation of an input future by a producer method. */
-  abstract static class FutureTransform {
-    protected final ImmutableMap<Key, FieldSpec> fields;
-    protected final ProductionBinding binding;
-
-    FutureTransform(ImmutableMap<Key, FieldSpec> fields, ProductionBinding binding) {
-      this.fields = fields;
-      this.binding = binding;
-    }
-
-    /** The code block representing the future that should be transformed. */
-    abstract CodeBlock futureCodeBlock();
-
-    /** The type of the argument to the apply method. */
-    abstract TypeName applyArgType();
-
-    /** The name of the argument to the apply method */
-    abstract String applyArgName();
-
-    /** The code blocks to be passed to the produces method itself. */
-    abstract ImmutableList<CodeBlock> parameterCodeBlocks();
-
-    /** Whether the transform method has an unchecked cast. */
-    boolean hasUncheckedCast() {
-      return false;
-    }
-
-    CodeBlock frameworkTypeUsageStatement(DependencyRequest dependency) {
-      return SourceFiles.frameworkTypeUsageStatement(
-          CodeBlock.of("$N", fields.get(dependency.key())), dependency.kind());
-    }
-
-    static FutureTransform create(
-        ImmutableMap<Key, FieldSpec> fields,
-        ProductionBinding binding,
-        ImmutableList<DependencyRequest> asyncDependencies) {
-      if (asyncDependencies.isEmpty()) {
-        return new NoArgFutureTransform(fields, binding);
-      } else if (asyncDependencies.size() == 1) {
-        return new SingleArgFutureTransform(
-            fields, binding, Iterables.getOnlyElement(asyncDependencies));
-      } else {
-        return new MultiArgFutureTransform(fields, binding, asyncDependencies);
-      }
-    }
-  }
-
-  static final class NoArgFutureTransform extends FutureTransform {
-    NoArgFutureTransform(ImmutableMap<Key, FieldSpec> fields, ProductionBinding binding) {
-      super(fields, binding);
-    }
-
-    @Override
-    CodeBlock futureCodeBlock() {
-      return CodeBlock.of("$T.<$T>immediateFuture(null)", FUTURES, VOID_CLASS);
-    }
-
-    @Override
-    TypeName applyArgType() {
-      return VOID_CLASS;
-    }
-
-    @Override
-    String applyArgName() {
-      return "ignoredVoidArg";
-    }
-
-    @Override
-    ImmutableList<CodeBlock> parameterCodeBlocks() {
-      return binding.explicitDependencies().stream()
-          .map(this::frameworkTypeUsageStatement)
-          .collect(toImmutableList());
-    }
-  }
-
-  static final class SingleArgFutureTransform extends FutureTransform {
-    private final DependencyRequest asyncDependency;
-
-    SingleArgFutureTransform(
-        ImmutableMap<Key, FieldSpec> fields,
-        ProductionBinding binding,
-        DependencyRequest asyncDependency) {
-      super(fields, binding);
-      this.asyncDependency = asyncDependency;
-    }
-
-    @Override
-    CodeBlock futureCodeBlock() {
-      return CodeBlock.of("$L", dependencyFutureName(asyncDependency));
-    }
-
-    @Override
-    TypeName applyArgType() {
-      return asyncDependencyType(asyncDependency);
-    }
-
-    @Override
-    String applyArgName() {
-      String argName = asyncDependency.requestElement().get().getSimpleName().toString();
-      if (argName.equals("module")) {
-        return "moduleArg";
-      }
-      return argName;
-    }
-
-    @Override
-    ImmutableList<CodeBlock> parameterCodeBlocks() {
-      ImmutableList.Builder<CodeBlock> parameterCodeBlocks = ImmutableList.builder();
-      for (DependencyRequest dependency : binding.explicitDependencies()) {
-        // We really want to compare instances here, because asyncDependency is an element in the
-        // set binding.dependencies().
-        if (dependency == asyncDependency) {
-          parameterCodeBlocks.add(CodeBlock.of("$L", applyArgName()));
-        } else {
-          parameterCodeBlocks.add(frameworkTypeUsageStatement(dependency));
-        }
-      }
-      return parameterCodeBlocks.build();
-    }
-  }
-
-  static final class MultiArgFutureTransform extends FutureTransform {
-    private final ImmutableList<DependencyRequest> asyncDependencies;
-
-    MultiArgFutureTransform(
-        ImmutableMap<Key, FieldSpec> fields,
-        ProductionBinding binding,
-        ImmutableList<DependencyRequest> asyncDependencies) {
-      super(fields, binding);
-      this.asyncDependencies = asyncDependencies;
-    }
-
-    @Override
-    CodeBlock futureCodeBlock() {
-      return CodeBlock.of(
-          "$T.<$T>allAsList($L)",
-          FUTURES,
-          OBJECT,
-          asyncDependencies
-              .stream()
-              .map(ProducerFactoryGenerator::dependencyFutureName)
-              .collect(joining(", ")));
-    }
-
-    @Override
-    TypeName applyArgType() {
-      return listOf(OBJECT);
-    }
-
-    @Override
-    String applyArgName() {
-      return "args";
-    }
-
-    @Override
-    ImmutableList<CodeBlock> parameterCodeBlocks() {
-      int argIndex = 0;
-      ImmutableList.Builder<CodeBlock> codeBlocks = ImmutableList.builder();
-      for (DependencyRequest dependency : binding.explicitDependencies()) {
-        if (isAsyncDependency(dependency)) {
-          codeBlocks.add(
-              CodeBlock.of(
-                  "($T) $L.get($L)", asyncDependencyType(dependency), applyArgName(), argIndex));
-          argIndex++;
-        } else {
-          codeBlocks.add(frameworkTypeUsageStatement(dependency));
-        }
-      }
-      return codeBlocks.build();
-    }
-
-    @Override
-    boolean hasUncheckedCast() {
-      return true;
-    }
-  }
-
-  private static boolean isAsyncDependency(DependencyRequest dependency) {
-    switch (dependency.kind()) {
-      case INSTANCE:
-      case PRODUCED:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  private static TypeName asyncDependencyType(DependencyRequest dependency) {
-    TypeName keyName = TypeName.get(dependency.key().type());
-    switch (dependency.kind()) {
-      case INSTANCE:
-        return keyName;
-      case PRODUCED:
-        return producedOf(keyName);
-      default:
-        throw new AssertionError();
-    }
-  }
-
-  /**
-   * Creates a code block for the invocation of the producer method from the module, which should be
-   * used entirely within a method body.
-   *
-   * @param binding The binding to generate the invocation code block for.
-   * @param providedTypeName The type name that should be provided by this producer.
-   * @param parameterCodeBlocks The code blocks for all the parameters to the producer method.
-   */
-  private CodeBlock getInvocationCodeBlock(
-      ProductionBinding binding,
-      TypeName providedTypeName,
-      ImmutableList<CodeBlock> parameterCodeBlocks) {
-    CodeBlock moduleCodeBlock =
-        CodeBlock.of(
-            "$L.$L($L)",
-            binding.requiresModuleInstance()
-                ? "module"
-                : CodeBlock.of("$T", ClassName.get(binding.bindingTypeElement().get())),
-            binding.bindingElement().get().getSimpleName(),
-            makeParametersCodeBlock(parameterCodeBlocks));
-
-    final CodeBlock returnCodeBlock;
-    switch (binding.productionKind().get()) {
-      case IMMEDIATE:
-        returnCodeBlock =
-            CodeBlock.of("$T.<$T>immediateFuture($L)", FUTURES, providedTypeName, moduleCodeBlock);
-        break;
-      case FUTURE:
-        returnCodeBlock = moduleCodeBlock;
-        break;
-      case SET_OF_FUTURE:
-        returnCodeBlock = CodeBlock.of("$T.allAsSet($L)", PRODUCERS, moduleCodeBlock);
-        break;
-      default:
-        throw new AssertionError();
-    }
-    return CodeBlock.of("return $L;", returnCodeBlock);
-  }
-
-  /**
-   * Converts the list of thrown types into type names.
-   *
-   * @param thrownTypes the list of thrown types.
-   */
-  private FluentIterable<? extends TypeName> getThrownTypeNames(
-      Iterable<? extends TypeMirror> thrownTypes) {
-    return FluentIterable.from(thrownTypes).transform(TypeName::get);
-  }
-}
diff --git a/java/dagger/internal/codegen/ProducerFromProviderCreationExpression.java b/java/dagger/internal/codegen/ProducerFromProviderCreationExpression.java
deleted file mode 100644
index aca9756..0000000
--- a/java/dagger/internal/codegen/ProducerFromProviderCreationExpression.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
-import dagger.internal.codegen.javapoet.TypeNames;
-import dagger.model.RequestKind;
-import dagger.producers.Producer;
-import java.util.Optional;
-
-/** An {@link Producer} creation expression for provision bindings. */
-final class ProducerFromProviderCreationExpression implements FrameworkInstanceCreationExpression {
-  private final ContributionBinding binding;
-  private final ComponentImplementation componentImplementation;
-  private final ComponentBindingExpressions componentBindingExpressions;
-
-  ProducerFromProviderCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions) {
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    return FrameworkType.PROVIDER.to(
-        RequestKind.PRODUCER,
-        componentBindingExpressions
-            .getDependencyExpression(
-                bindingRequest(binding.key(), FrameworkType.PROVIDER),
-                componentImplementation.name())
-            .codeBlock());
-  }
-
-  @Override
-  public Optional<ClassName> alternativeFrameworkClass() {
-    return Optional.of(TypeNames.PRODUCER);
-  }
-
-  // TODO(ronshapiro): should this have a simple factory if the delegate expression is simple?
-}
diff --git a/java/dagger/internal/codegen/ProducerNodeInstanceBindingExpression.java b/java/dagger/internal/codegen/ProducerNodeInstanceBindingExpression.java
deleted file mode 100644
index 18818d5..0000000
--- a/java/dagger/internal/codegen/ProducerNodeInstanceBindingExpression.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-
-import com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-
-/** Binding expression for producer node instances. */
-final class ProducerNodeInstanceBindingExpression extends FrameworkInstanceBindingExpression {
-  /** The component defining this binding. */
-  private final ComponentImplementation componentImplementation;
-  private final Key key;
-  private final ProducerEntryPointView producerEntryPointView;
-
-  ProducerNodeInstanceBindingExpression(
-      ResolvedBindings resolvedBindings,
-      FrameworkInstanceSupplier frameworkInstanceSupplier,
-      DaggerTypes types,
-      DaggerElements elements,
-      ComponentImplementation componentImplementation) {
-    super(resolvedBindings, frameworkInstanceSupplier, types, elements);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.key = resolvedBindings.key();
-    this.producerEntryPointView = new ProducerEntryPointView(types);
-  }
-
-  @Override
-  protected FrameworkType frameworkType() {
-    return FrameworkType.PRODUCER_NODE;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    Expression result = super.getDependencyExpression(requestingClass);
-    componentImplementation.addCancellableProducerKey(key);
-    return result;
-  }
-
-  @Override
-  Expression getDependencyExpressionForComponentMethod(
-      ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
-    return producerEntryPointView
-        .getProducerEntryPointField(this, componentMethod, component)
-        .orElseGet(
-            () -> super.getDependencyExpressionForComponentMethod(componentMethod, component));
-  }
-}
diff --git a/java/dagger/internal/codegen/ProducesMethodValidator.java b/java/dagger/internal/codegen/ProducesMethodValidator.java
deleted file mode 100644
index bf45948..0000000
--- a/java/dagger/internal/codegen/ProducesMethodValidator.java
+++ /dev/null
@@ -1,133 +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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingElementValidator.AllowsMultibindings.ALLOWS_MULTIBINDINGS;
-import static dagger.internal.codegen.BindingElementValidator.AllowsScoping.NO_SCOPING;
-import static dagger.internal.codegen.BindingMethodValidator.Abstractness.MUST_BE_CONCRETE;
-import static dagger.internal.codegen.BindingMethodValidator.ExceptionSuperclass.EXCEPTION;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.util.Optional;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** A validator for {@link Produces} methods. */
-final class ProducesMethodValidator extends BindingMethodValidator {
-
-  @Inject
-  ProducesMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator) {
-    super(
-        elements,
-        types,
-        dependencyRequestValidator,
-        Produces.class,
-        ProducerModule.class,
-        MUST_BE_CONCRETE,
-        EXCEPTION,
-        ALLOWS_MULTIBINDINGS,
-        NO_SCOPING);
-  }
-
-  @Override
-  protected String elementsIntoSetNotASetMessage() {
-    return "@Produces methods of type set values must return a Set or ListenableFuture of Set";
-  }
-
-  @Override
-  protected String badTypeMessage() {
-    return "@Produces methods can return only a primitive, an array, a type variable, "
-        + "a declared type, or a ListenableFuture of one of those types";
-  }
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends MethodValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkAdditionalMethodProperties() {
-      checkNullable();
-    }
-
-    /** Adds a warning if a {@link Produces @Produces} method is declared nullable. */
-    // TODO(beder): Properly handle nullable with producer methods.
-    private void checkNullable() {
-      if (ConfigurationAnnotations.getNullableType(element).isPresent()) {
-        report.addWarning("@Nullable on @Produces methods does not do anything");
-      }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Allows {@code keyType} to be a {@link ListenableFuture} of an otherwise-valid key type.
-     */
-    @Override
-    protected void checkKeyType(TypeMirror keyType) {
-      Optional<TypeMirror> typeToCheck = unwrapListenableFuture(keyType);
-      if (typeToCheck.isPresent()) {
-        super.checkKeyType(typeToCheck.get());
-      }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Allows an {@link ElementsIntoSet @ElementsIntoSet} or {@code SET_VALUES} method to return
-     * a {@link ListenableFuture} of a {@link Set} as well.
-     */
-    @Override
-    protected void checkSetValuesType() {
-      Optional<TypeMirror> typeToCheck = unwrapListenableFuture(element.getReturnType());
-      if (typeToCheck.isPresent()) {
-        checkSetValuesType(typeToCheck.get());
-      }
-    }
-
-    private Optional<TypeMirror> unwrapListenableFuture(TypeMirror type) {
-      if (MoreTypes.isType(type) && MoreTypes.isTypeOf(ListenableFuture.class, type)) {
-        DeclaredType declaredType = MoreTypes.asDeclared(type);
-        if (declaredType.getTypeArguments().isEmpty()) {
-          report.addError("@Produces methods cannot return a raw ListenableFuture");
-          return Optional.empty();
-        } else {
-          return Optional.of((TypeMirror) getOnlyElement(declaredType.getTypeArguments()));
-        }
-      }
-      return Optional.of(type);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ProductionBinding.java b/java/dagger/internal/codegen/ProductionBinding.java
deleted file mode 100644
index a22f21c..0000000
--- a/java/dagger/internal/codegen/ProductionBinding.java
+++ /dev/null
@@ -1,146 +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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.langmodel.DaggerTypes.isFutureType;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import java.util.Optional;
-import java.util.stream.Stream;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A value object representing the mechanism by which a {@link Key} can be produced.
- */
-@AutoValue
-abstract class ProductionBinding extends ContributionBinding {
-
-  @Override
-  public BindingType bindingType() {
-    return BindingType.PRODUCTION;
-  }
-
-  @Override
-  abstract Optional<ProductionBinding> unresolved();
-
-  @Override
-  ImmutableSet<DependencyRequest> implicitDependencies() {
-    return Stream.of(executorRequest(), monitorRequest())
-        .filter(Optional::isPresent)
-        .map(Optional::get)
-        .collect(toImmutableSet());
-  }
-
-  /** What kind of object a {@code @Produces}-annotated method returns. */
-  enum ProductionKind {
-    /** A value. */
-    IMMEDIATE,
-    /** A {@code ListenableFuture<T>}. */
-    FUTURE,
-    /** A {@code Set<ListenableFuture<T>>}. */
-    SET_OF_FUTURE;
-
-    /** Returns the kind of object a {@code @Produces}-annotated method returns. */
-    static ProductionKind fromProducesMethod(ExecutableElement producesMethod) {
-      if (isFutureType(producesMethod.getReturnType())) {
-        return FUTURE;
-      } else if (ContributionType.fromBindingElement(producesMethod)
-              .equals(ContributionType.SET_VALUES)
-          && isFutureType(SetType.from(producesMethod.getReturnType()).elementType())) {
-        return SET_OF_FUTURE;
-      } else {
-        return IMMEDIATE;
-      }
-    }
-  }
-
-  /**
-   * Returns the kind of object the produces method returns. All production bindings from
-   * {@code @Produces} methods will have a production kind, but synthetic production bindings may
-   * not.
-   */
-  abstract Optional<ProductionKind> productionKind();
-
-  /** Returns the list of types in the throws clause of the method. */
-  abstract ImmutableList<? extends TypeMirror> thrownTypes();
-
-  /**
-   * If this production requires an executor, this will be the corresponding request.  All
-   * production bindings from {@code @Produces} methods will have an executor request, but
-   * synthetic production bindings may not.
-   */
-  abstract Optional<DependencyRequest> executorRequest();
-
-  /** If this production requires a monitor, this will be the corresponding request.  All
-   * production bindings from {@code @Produces} methods will have a monitor request, but synthetic
-   * production bindings may not.
-   */
-  abstract Optional<DependencyRequest> monitorRequest();
-
-  // Profiling determined that this method is called enough times that memoizing it had a measurable
-  // performance improvement for large components.
-  @Memoized
-  @Override
-  boolean requiresModuleInstance() {
-    return super.requiresModuleInstance();
-  }
-
-  static Builder builder() {
-    return new AutoValue_ProductionBinding.Builder()
-        .explicitDependencies(ImmutableList.<DependencyRequest>of())
-        .thrownTypes(ImmutableList.<TypeMirror>of());
-  }
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  // TODO(ronshapiro,dpb): simplify the equality semantics
-  @Override
-  public abstract boolean equals(Object obj);
-
-  @AutoValue.Builder
-  @CanIgnoreReturnValue
-  abstract static class Builder extends ContributionBinding.Builder<ProductionBinding, Builder> {
-
-    @Override
-    Builder dependencies(Iterable<DependencyRequest> dependencies) {
-      return explicitDependencies(dependencies);
-    }
-
-    abstract Builder explicitDependencies(Iterable<DependencyRequest> dependencies);
-
-    abstract Builder productionKind(ProductionKind productionKind);
-
-    @Override
-    abstract Builder unresolved(ProductionBinding unresolved);
-
-    abstract Builder thrownTypes(Iterable<? extends TypeMirror> thrownTypes);
-
-    abstract Builder executorRequest(DependencyRequest executorRequest);
-
-    abstract Builder monitorRequest(DependencyRequest monitorRequest);
-  }
-}
diff --git a/java/dagger/internal/codegen/ProviderInstanceBindingExpression.java b/java/dagger/internal/codegen/ProviderInstanceBindingExpression.java
deleted file mode 100644
index 60166de..0000000
--- a/java/dagger/internal/codegen/ProviderInstanceBindingExpression.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-
-/** Binding expression for provider instances. */
-final class ProviderInstanceBindingExpression extends FrameworkInstanceBindingExpression {
-
-  ProviderInstanceBindingExpression(
-      ResolvedBindings resolvedBindings,
-      FrameworkInstanceSupplier frameworkInstanceSupplier,
-      DaggerTypes types,
-      DaggerElements elements) {
-    super(
-        resolvedBindings,
-        frameworkInstanceSupplier,
-        types,
-        elements);
-  }
-
-  @Override
-  protected FrameworkType frameworkType() {
-    return FrameworkType.PROVIDER;
-  }
-}
diff --git a/java/dagger/internal/codegen/ProvidesMethodValidator.java b/java/dagger/internal/codegen/ProvidesMethodValidator.java
deleted file mode 100644
index 01e71ae..0000000
--- a/java/dagger/internal/codegen/ProvidesMethodValidator.java
+++ /dev/null
@@ -1,78 +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 dagger.internal.codegen.BindingElementValidator.AllowsMultibindings.ALLOWS_MULTIBINDINGS;
-import static dagger.internal.codegen.BindingElementValidator.AllowsScoping.ALLOWS_SCOPING;
-import static dagger.internal.codegen.BindingMethodValidator.Abstractness.MUST_BE_CONCRETE;
-import static dagger.internal.codegen.BindingMethodValidator.ExceptionSuperclass.RUNTIME_EXCEPTION;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.producers.ProducerModule;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-
-/** A validator for {@link Provides} methods. */
-final class ProvidesMethodValidator extends BindingMethodValidator {
-
-  private final DependencyRequestValidator dependencyRequestValidator;
-
-  @Inject
-  ProvidesMethodValidator(
-      DaggerElements elements,
-      DaggerTypes types,
-      DependencyRequestValidator dependencyRequestValidator) {
-    super(
-        elements,
-        types,
-        Provides.class,
-        ImmutableSet.of(Module.class, ProducerModule.class),
-        dependencyRequestValidator,
-        MUST_BE_CONCRETE,
-        RUNTIME_EXCEPTION,
-        ALLOWS_MULTIBINDINGS,
-        ALLOWS_SCOPING);
-    this.dependencyRequestValidator = dependencyRequestValidator;
-  }
-
-  @Override
-  protected ElementValidator elementValidator(ExecutableElement element) {
-    return new Validator(element);
-  }
-
-  private class Validator extends MethodValidator {
-    Validator(ExecutableElement element) {
-      super(element);
-    }
-
-    @Override
-    protected void checkAdditionalMethodProperties() {
-    }
-
-    /** Adds an error if a {@link Provides @Provides} method depends on a producer type. */
-    @Override
-    protected void checkParameter(VariableElement parameter) {
-      super.checkParameter(parameter);
-      dependencyRequestValidator.checkNotProducer(report, parameter);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ProvisionBinding.java b/java/dagger/internal/codegen/ProvisionBinding.java
deleted file mode 100644
index 306cb13..0000000
--- a/java/dagger/internal/codegen/ProvisionBinding.java
+++ /dev/null
@@ -1,135 +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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.model.BindingKind.COMPONENT_PROVISION;
-import static dagger.model.BindingKind.PROVISION;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
-import dagger.model.BindingKind;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.Scope;
-import java.util.Optional;
-
-/**
- * A value object representing the mechanism by which a {@link Key} can be provided.
- */
-@AutoValue
-abstract class ProvisionBinding extends ContributionBinding {
-
-  @Override
-  @Memoized
-  ImmutableSet<DependencyRequest> explicitDependencies() {
-    return ImmutableSet.<DependencyRequest>builder()
-        .addAll(provisionDependencies())
-        .addAll(membersInjectionDependencies())
-        .build();
-  }
-
-  /**
-   * Dependencies necessary to invoke an {@code @Inject} constructor or {@code @Provides} method.
-   */
-  abstract ImmutableSet<DependencyRequest> provisionDependencies();
-
-  @Memoized
-  ImmutableSet<DependencyRequest> membersInjectionDependencies() {
-    return injectionSites()
-        .stream()
-        .flatMap(i -> i.dependencies().stream())
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * {@link InjectionSite}s for all {@code @Inject} members if {@link #kind()} is {@link
-   * BindingKind#INJECTION}, otherwise empty.
-   */
-  abstract ImmutableSortedSet<InjectionSite> injectionSites();
-
-  @Override
-  public BindingType bindingType() {
-    return BindingType.PROVISION;
-  }
-
-  @Override
-  abstract Optional<ProvisionBinding> unresolved();
-
-  // TODO(ronshapiro): we should be able to remove this, but AutoValue barks on the Builder's scope
-  // method, saying that the method doesn't correspond to a property of ProvisionBinding
-  @Override
-  public abstract Optional<Scope> scope();
-
-  static Builder builder() {
-    return new AutoValue_ProvisionBinding.Builder()
-        .provisionDependencies(ImmutableSet.of())
-        .injectionSites(ImmutableSortedSet.of());
-  }
-
-  abstract Builder toBuilder();
-
-  private static final ImmutableSet<BindingKind> KINDS_TO_CHECK_FOR_NULL =
-      ImmutableSet.of(PROVISION, COMPONENT_PROVISION);
-
-  boolean shouldCheckForNull(CompilerOptions compilerOptions) {
-    return KINDS_TO_CHECK_FOR_NULL.contains(kind())
-        && !contributedPrimitiveType().isPresent()
-        && !nullableType().isPresent()
-        && compilerOptions.doCheckForNulls();
-  }
-
-  // Profiling determined that this method is called enough times that memoizing it had a measurable
-  // performance improvement for large components.
-  @Memoized
-  @Override
-  boolean requiresModuleInstance() {
-    return super.requiresModuleInstance();
-  }
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  // TODO(ronshapiro,dpb): simplify the equality semantics
-  @Override
-  public abstract boolean equals(Object obj);
-
-  @AutoValue.Builder
-  @CanIgnoreReturnValue
-  abstract static class Builder extends ContributionBinding.Builder<ProvisionBinding, Builder> {
-
-    @Override
-    Builder dependencies(Iterable<DependencyRequest> dependencies) {
-      return provisionDependencies(dependencies);
-    }
-
-    abstract Builder provisionDependencies(Iterable<DependencyRequest> provisionDependencies);
-
-    abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites);
-
-    @Override
-    abstract Builder unresolved(ProvisionBinding unresolved);
-
-    abstract Builder scope(Optional<Scope> scope);
-  }
-
-}
diff --git a/java/dagger/internal/codegen/ProvisionDependencyOnProducerBindingValidator.java b/java/dagger/internal/codegen/ProvisionDependencyOnProducerBindingValidator.java
deleted file mode 100644
index 2fb1a0e..0000000
--- a/java/dagger/internal/codegen/ProvisionDependencyOnProducerBindingValidator.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2018 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.Verify.verify;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.RequestKinds.canBeSatisfiedByProductionBinding;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.Node;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.stream.Stream;
-import javax.inject.Inject;
-
-/**
- * Reports an error for each provision-only dependency request that is satisfied by a production
- * binding.
- */
-// TODO(b/29509141): Clarify the error.
-final class ProvisionDependencyOnProducerBindingValidator implements BindingGraphPlugin {
-
-  @Inject
-  ProvisionDependencyOnProducerBindingValidator() {}
-
-  @Override
-  public String pluginName() {
-    return "Dagger/ProviderDependsOnProducer";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    provisionDependenciesOnProductionBindings(bindingGraph)
-        .forEach(
-            provisionDependent ->
-                diagnosticReporter.reportDependency(
-                    ERROR,
-                    provisionDependent,
-                    provisionDependent.isEntryPoint()
-                        ? entryPointErrorMessage(provisionDependent)
-                        : dependencyErrorMessage(provisionDependent, bindingGraph)));
-  }
-
-  private Stream<DependencyEdge> provisionDependenciesOnProductionBindings(
-      BindingGraph bindingGraph) {
-    return bindingGraph.bindings().stream()
-        .filter(binding -> binding.isProduction())
-        .flatMap(binding -> incomingDependencies(binding, bindingGraph))
-        .filter(edge -> !dependencyCanUseProduction(edge, bindingGraph));
-  }
-
-  /** Returns the dependencies on {@code binding}. */
-  // TODO(dpb): Move to BindingGraph.
-  private Stream<DependencyEdge> incomingDependencies(
-      dagger.model.Binding binding, BindingGraph bindingGraph) {
-    return bindingGraph.network().inEdges(binding).stream()
-        .flatMap(instancesOf(DependencyEdge.class));
-  }
-
-  // TODO(ronshapiro): merge with MissingBindingValidator.dependencyCanUseProduction
-  private boolean dependencyCanUseProduction(DependencyEdge edge, BindingGraph bindingGraph) {
-    return edge.isEntryPoint()
-        ? canBeSatisfiedByProductionBinding(edge.dependencyRequest().kind())
-        : bindingRequestingDependency(edge, bindingGraph).isProduction();
-  }
-
-  /**
-   * Returns the binding that requests a dependency.
-   *
-   * @throws IllegalArgumentException if {@code dependency} is an {@linkplain
-   *     DependencyEdge#isEntryPoint() entry point}.
-   */
-  // TODO(dpb): Move to BindingGraph.
-  private dagger.model.Binding bindingRequestingDependency(
-      DependencyEdge dependency, BindingGraph bindingGraph) {
-    checkArgument(!dependency.isEntryPoint());
-    Node source = bindingGraph.network().incidentNodes(dependency).source();
-    verify(
-        source instanceof dagger.model.Binding,
-        "expected source of %s to be a binding, but was: %s",
-        dependency,
-        source);
-    return (dagger.model.Binding) source;
-  }
-
-  private String entryPointErrorMessage(DependencyEdge entryPoint) {
-    return String.format(
-        "%s is a provision entry-point, which cannot depend on a production.",
-        entryPoint.dependencyRequest().key());
-  }
-
-  private String dependencyErrorMessage(
-      DependencyEdge dependencyOnProduction, BindingGraph bindingGraph) {
-    return String.format(
-        "%s is a provision, which cannot depend on a production.",
-        bindingRequestingDependency(dependencyOnProduction, bindingGraph).key());
-  }
-}
diff --git a/java/dagger/internal/codegen/PrunedConcreteMethodBindingExpression.java b/java/dagger/internal/codegen/PrunedConcreteMethodBindingExpression.java
deleted file mode 100644
index 6eb92ac..0000000
--- a/java/dagger/internal/codegen/PrunedConcreteMethodBindingExpression.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.MissingBindingFactory;
-import dagger.internal.codegen.ModifiableBindingMethods.ModifiableBindingMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.producers.internal.MissingBindingProducer;
-import java.util.Optional;
-
-/**
- * A {@link BindingExpression} that implements a method that encapsulates a binding that is not part
- * of the binding graph when generating a final concrete implementation of a subcomponent. The
- * implementation throws an exception. It is assumed that a binding may remain missing in a valid
- * binding graph, because it's possible for there to be dependencies that are passively pruned when
- * a non-leaf binding is re-defined (such as when {@code @Provides} bindings override
- * {@code @Inject} bindings).
- *
- * <p>This method should never be invoked. If it is the exception indicates an issue within Dagger
- * itself.
- */
-final class PrunedConcreteMethodBindingExpression extends BindingExpression {
-  private static final CodeBlock METHOD_IMPLEMENTATION =
-      CodeBlock.of(
-          "throw new $T($S);",
-          UnsupportedOperationException.class,
-          "This binding is not part of the final binding graph. The key was requested by a binding "
-              + "that was believed to possibly be part of the graph, but is no longer requested. "
-              + "If this exception is thrown, it is the result of a Dagger bug.");
-
-  PrunedConcreteMethodBindingExpression() {}
-
-  @Override
-  CodeBlock getModifiableBindingMethodImplementation(
-      ModifiableBindingMethod modifiableBindingMethod,
-      ComponentImplementation component,
-      DaggerTypes types) {
-    Optional<FrameworkType> frameworkType = modifiableBindingMethod.request().frameworkType();
-    if (frameworkType.isPresent()) {
-      // If we make initializations replaceable, we can do away with these classes and this logic
-      // since the pruned framework instances will no longer be initialized
-      switch (frameworkType.get()) {
-        case PROVIDER:
-          return missingFrameworkInstance(MissingBindingFactory.class);
-        case PRODUCER_NODE:
-          return missingFrameworkInstance(MissingBindingProducer.class);
-      }
-      throw new AssertionError(frameworkType);
-    }
-    return METHOD_IMPLEMENTATION;
-  }
-
-  private static CodeBlock missingFrameworkInstance(Class<?> factoryClass) {
-    return CodeBlock.builder().addStatement("return $T.create()", factoryClass).build();
-  }
-
-  @Override
-  final Expression getDependencyExpression(ClassName requestingClass) {
-    throw new UnsupportedOperationException(
-        "Requesting a dependency expression for a pruned binding.");
-  }
-}
diff --git a/java/dagger/internal/codegen/RequestKinds.java b/java/dagger/internal/codegen/RequestKinds.java
deleted file mode 100644
index aa17f5e..0000000
--- a/java/dagger/internal/codegen/RequestKinds.java
+++ /dev/null
@@ -1,203 +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.auto.common.MoreTypes.asDeclared;
-import static com.google.auto.common.MoreTypes.isType;
-import static com.google.auto.common.MoreTypes.isTypeOf;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.javapoet.TypeNames.lazyOf;
-import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf;
-import static dagger.internal.codegen.javapoet.TypeNames.producedOf;
-import static dagger.internal.codegen.javapoet.TypeNames.producerOf;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-import static dagger.internal.codegen.langmodel.DaggerTypes.checkTypePresent;
-import static dagger.model.RequestKind.INSTANCE;
-import static dagger.model.RequestKind.LAZY;
-import static dagger.model.RequestKind.PRODUCED;
-import static dagger.model.RequestKind.PRODUCER;
-import static dagger.model.RequestKind.PROVIDER;
-import static dagger.model.RequestKind.PROVIDER_OF_LAZY;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.squareup.javapoet.TypeName;
-import dagger.Lazy;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.RequestKind;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import javax.inject.Provider;
-import javax.lang.model.type.TypeMirror;
-
-/** Utility methods for {@link RequestKind}s. */
-final class RequestKinds {
-  /** Returns the type of a request of this kind for a key with a given type. */
-  static TypeMirror requestType(RequestKind requestKind, TypeMirror type, DaggerTypes types) {
-    switch (requestKind) {
-      case INSTANCE:
-        return type;
-
-      case PROVIDER_OF_LAZY:
-        return types.wrapType(requestType(LAZY, type, types), Provider.class);
-
-      case FUTURE:
-        return types.wrapType(type, ListenableFuture.class);
-
-      default:
-        return types.wrapType(type, frameworkClass(requestKind));
-    }
-  }
-
-  /** Returns the type of a request of this kind for a key with a given type. */
-  static TypeName requestTypeName(RequestKind requestKind, TypeName keyType) {
-    switch (requestKind) {
-      case INSTANCE:
-        return keyType;
-
-      case PROVIDER:
-        return providerOf(keyType);
-
-      case LAZY:
-        return lazyOf(keyType);
-
-      case PROVIDER_OF_LAZY:
-        return providerOf(lazyOf(keyType));
-
-      case PRODUCER:
-        return producerOf(keyType);
-
-      case PRODUCED:
-        return producedOf(keyType);
-
-      case FUTURE:
-        return listenableFutureOf(keyType);
-
-      default:
-        throw new AssertionError(requestKind);
-    }
-  }
-
-  private static final ImmutableMap<RequestKind, Class<?>> FRAMEWORK_CLASSES =
-      ImmutableMap.of(
-          PROVIDER, Provider.class,
-          LAZY, Lazy.class,
-          PRODUCER, Producer.class,
-          PRODUCED, Produced.class);
-
-  /** Returns the {@link RequestKind} that matches the wrapping types (if any) of {@code type}. */
-  static RequestKind getRequestKind(TypeMirror type) {
-    checkTypePresent(type);
-    for (RequestKind kind : FRAMEWORK_CLASSES.keySet()) {
-      if (matchesKind(kind, type)) {
-        if (kind.equals(PROVIDER) && matchesKind(LAZY, extractKeyType(kind, type))) {
-          return PROVIDER_OF_LAZY;
-        }
-        return kind;
-      }
-    }
-    return INSTANCE;
-  }
-
-  /**
-   * Returns {@code true} if {@code type} is a parameterized type of {@code kind}'s {@link
-   * #frameworkClass(RequestKind) framework class}.
-   */
-  private static boolean matchesKind(RequestKind kind, TypeMirror type) {
-    return isType(type)
-        && isTypeOf(frameworkClass(kind), type)
-        && !asDeclared(type).getTypeArguments().isEmpty();
-  }
-
-  /**
-   * Unwraps the framework class(es) of {@code requestKind} from {@code type}. If {@code
-   * requestKind} is {@link RequestKind#INSTANCE}, this acts as an identity function.
-   *
-   * @throws TypeNotPresentException if {@code type} is an {@link javax.lang.model.type.ErrorType},
-   *     which may mean that the type will be generated in a later round of processing
-   * @throws IllegalArgumentException if {@code type} is not wrapped with {@code requestKind}'s
-   *     framework class(es).
-   */
-  static TypeMirror extractKeyType(RequestKind requestKind, TypeMirror type) {
-    checkTypePresent(type);
-    switch (requestKind) {
-      case INSTANCE:
-        return type;
-      case PROVIDER_OF_LAZY:
-        return extractKeyType(LAZY, extractKeyType(PROVIDER, type));
-      default:
-        checkArgument(isType(type) && isTypeOf(frameworkClass(requestKind), type));
-        return getOnlyElement(MoreTypes.asDeclared(type).getTypeArguments());
-    }
-  }
-
-  /**
-   * A dagger- or {@code javax.inject}-defined class for {@code requestKind} that that can wrap
-   * another type but share the same {@link dagger.model.Key}.
-   *
-   * <p>For example, {@code Provider<String>} and {@code Lazy<String>} can both be requested if a
-   * key exists for {@code String}; they all share the same key.
-   *
-   * <p>This concept is not well defined and should probably be removed and inlined into the cases
-   * that need it. For example, {@link RequestKind#PROVIDER_OF_LAZY} has <em>2</em> wrapping
-   * classes, and {@link RequestKind#FUTURE} is wrapped with a {@link ListenableFuture}, but for
-   * historical/implementation reasons has not had an associated framework class.
-   */
-  static Class<?> frameworkClass(RequestKind requestKind) {
-    Class<?> result = FRAMEWORK_CLASSES.get(requestKind);
-    checkArgument(result != null, "no framework class for %s", requestKind);
-    return result;
-  }
-
-  /**
-   * Returns {@code true} if requests for {@code requestKind} can be satisfied by a production
-   * binding.
-   */
-  static boolean canBeSatisfiedByProductionBinding(RequestKind requestKind) {
-    switch (requestKind) {
-      case INSTANCE:
-      case PROVIDER:
-      case LAZY:
-      case PROVIDER_OF_LAZY:
-      case MEMBERS_INJECTION:
-        return false;
-      case PRODUCER:
-      case PRODUCED:
-      case FUTURE:
-        return true;
-    }
-    throw new AssertionError();
-  }
-
-  /**
-   * Returns true if {@code requestKind} is always derived from a {@link RequestKind#PROVIDER}
-   * instance.
-   */
-  static boolean isDerivedFromProvider(RequestKind requestKind) {
-    switch (requestKind) {
-      case LAZY:
-      case PROVIDER_OF_LAZY:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  private RequestKinds() {}
-}
diff --git a/java/dagger/internal/codegen/ResolvedBindings.java b/java/dagger/internal/codegen/ResolvedBindings.java
deleted file mode 100644
index 814995a..0000000
--- a/java/dagger/internal/codegen/ResolvedBindings.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkState;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-import dagger.internal.codegen.ContributionType.HasContributionType;
-import dagger.model.Key;
-import dagger.model.Scope;
-import java.util.Optional;
-import javax.lang.model.element.TypeElement;
-
-/**
- * The collection of bindings that have been resolved for a key. For valid graphs, contains exactly
- * one binding.
- *
- * <p>Separate {@link ResolvedBindings} instances should be used if a {@link
- * MembersInjectionBinding} and a {@link ProvisionBinding} for the same key exist in the same
- * component. (This will only happen if a type has an {@code @Inject} constructor and members, the
- * component has a members injection method, and the type is also requested normally.)
- */
-@AutoValue
-abstract class ResolvedBindings implements HasContributionType {
-  /**
-   * The binding key for which the {@link #bindings()} have been resolved.
-   */
-  abstract Key key();
-
-  /**
-   * The {@link ContributionBinding}s for {@link #key()} indexed by the component that owns the
-   * binding. Each key in the multimap is a part of the same component ancestry.
-   */
-  abstract ImmutableSetMultimap<TypeElement, ContributionBinding> allContributionBindings();
-
-  /**
-   * The {@link MembersInjectionBinding}s for {@link #key()} indexed by the component that owns the
-   * binding.  Each key in the map is a part of the same component ancestry.
-   */
-  abstract ImmutableMap<TypeElement, MembersInjectionBinding> allMembersInjectionBindings();
-
-  /** The multibinding declarations for {@link #key()}. */
-  abstract ImmutableSet<MultibindingDeclaration> multibindingDeclarations();
-
-  /** The subcomponent declarations for {@link #key()}. */
-  abstract ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations();
-
-  /**
-   * The optional binding declarations for {@link #key()}.
-   */
-  abstract ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations();
-
-  // Computing the hash code is an expensive operation.
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  // Suppresses ErrorProne warning that hashCode was overridden w/o equals
-  @Override
-  public abstract boolean equals(Object other);
-
-  /** All bindings for {@link #key()}, indexed by the component that owns the binding. */
-  final ImmutableSetMultimap<TypeElement, ? extends Binding> allBindings() {
-    return !allMembersInjectionBindings().isEmpty()
-        ? allMembersInjectionBindings().asMultimap()
-        : allContributionBindings();
-  }
-
-  /** All bindings for {@link #key()}, regardless of which component owns them. */
-  final ImmutableCollection<? extends Binding> bindings() {
-    return allBindings().values();
-  }
-
-  /**
-   * Returns the single binding.
-   *
-   * @throws IllegalStateException if there is not exactly one element in {@link #bindings()}, which
-   *     will never happen for contributions in valid graphs
-   */
-  final Binding binding() {
-    return getOnlyElement(bindings());
-  }
-
-  /**
-   * {@code true} if there are no {@link #bindings()}, {@link #multibindingDeclarations()}, {@link
-   * #optionalBindingDeclarations()}, or {@link #subcomponentDeclarations()}.
-   */
-  final boolean isEmpty() {
-    return allMembersInjectionBindings().isEmpty()
-        && allContributionBindings().isEmpty()
-        && multibindingDeclarations().isEmpty()
-        && optionalBindingDeclarations().isEmpty()
-        && subcomponentDeclarations().isEmpty();
-  }
-
-  /** All bindings for {@link #key()} that are owned by a component. */
-  ImmutableSet<? extends Binding> bindingsOwnedBy(ComponentDescriptor component) {
-    return allBindings().get(component.typeElement());
-  }
-
-  /**
-   * All contribution bindings, regardless of owning component. Empty if this is a members-injection
-   * binding.
-   */
-  @Memoized
-  ImmutableSet<ContributionBinding> contributionBindings() {
-    // TODO(ronshapiro): consider optimizing ImmutableSet.copyOf(Collection) for small immutable
-    // collections so that it doesn't need to call toArray(). Even though this method is memoized,
-    // toArray() can take ~150ms for large components, and there are surely other places in the
-    // processor that can benefit from this.
-    return ImmutableSet.copyOf(allContributionBindings().values());
-  }
-
-  /** The component that owns {@code binding}. */
-  final TypeElement owningComponent(ContributionBinding binding) {
-    checkArgument(
-        contributionBindings().contains(binding),
-        "binding is not resolved for %s: %s",
-        key(),
-        binding);
-    return getOnlyElement(allContributionBindings().inverse().get(binding));
-  }
-
-  /**
-   * The members-injection binding, regardless of owning component. Absent if these are contribution
-   * bindings, or if there is no members-injection binding because the type fails validation.
-   */
-  final Optional<MembersInjectionBinding> membersInjectionBinding() {
-    return allMembersInjectionBindings().isEmpty()
-        ? Optional.empty()
-        : Optional.of(Iterables.getOnlyElement(allMembersInjectionBindings().values()));
-  }
-
-  /** Creates a {@link ResolvedBindings} for contribution bindings. */
-  static ResolvedBindings forContributionBindings(
-      Key key,
-      Multimap<TypeElement, ContributionBinding> contributionBindings,
-      Iterable<MultibindingDeclaration> multibindings,
-      Iterable<SubcomponentDeclaration> subcomponentDeclarations,
-      Iterable<OptionalBindingDeclaration> optionalBindingDeclarations) {
-    return new AutoValue_ResolvedBindings(
-        key,
-        ImmutableSetMultimap.copyOf(contributionBindings),
-        ImmutableMap.of(),
-        ImmutableSet.copyOf(multibindings),
-        ImmutableSet.copyOf(subcomponentDeclarations),
-        ImmutableSet.copyOf(optionalBindingDeclarations));
-  }
-
-  /**
-   * Creates a {@link ResolvedBindings} for members injection bindings.
-   */
-  static ResolvedBindings forMembersInjectionBinding(
-      Key key,
-      ComponentDescriptor owningComponent,
-      MembersInjectionBinding ownedMembersInjectionBinding) {
-    return new AutoValue_ResolvedBindings(
-        key,
-        ImmutableSetMultimap.of(),
-        ImmutableMap.of(owningComponent.typeElement(), ownedMembersInjectionBinding),
-        ImmutableSet.of(),
-        ImmutableSet.of(),
-        ImmutableSet.of());
-  }
-
-  /**
-   * Creates a {@link ResolvedBindings} appropriate for when there are no bindings for the key.
-   */
-  static ResolvedBindings noBindings(Key key) {
-    return new AutoValue_ResolvedBindings(
-        key,
-        ImmutableSetMultimap.of(),
-        ImmutableMap.of(),
-        ImmutableSet.of(),
-        ImmutableSet.of(),
-        ImmutableSet.of());
-  }
-
-  /**
-   * {@code true} if this is a multibinding contribution.
-   */
-  boolean isMultibindingContribution() {
-    return contributionBindings().size() == 1
-        && contributionBinding().contributionType().isMultibinding();
-  }
-
-  /**
-   * Returns the single contribution binding.
-   *
-   * @throws IllegalStateException if there is not exactly one element in
-   *     {@link #contributionBindings()}, which will never happen for contributions in valid graphs
-   */
-  ContributionBinding contributionBinding() {
-    return getOnlyElement(contributionBindings());
-  }
-
-  /**
-   * The binding type for these bindings. If there are {@link #multibindingDeclarations()} or {@link
-   * #subcomponentDeclarations()} but no {@link #bindings()}, returns {@link BindingType#PROVISION}.
-   *
-   * @throws IllegalStateException if {@link #isEmpty()} or the binding types conflict
-   */
-  final BindingType bindingType() {
-    checkState(!isEmpty(), "empty bindings for %s", key());
-    if (allBindings().isEmpty()
-        && (!multibindingDeclarations().isEmpty() || !subcomponentDeclarations().isEmpty())) {
-      // Only multibinding declarations, so assume provision.
-      return BindingType.PROVISION;
-    }
-    ImmutableSet<BindingType> bindingTypes = bindingTypes();
-    checkState(bindingTypes.size() == 1, "conflicting binding types: %s", bindings());
-    return getOnlyElement(bindingTypes);
-  }
-
-  /** The binding types for {@link #bindings()}. */
-  @Memoized
-  ImmutableSet<BindingType> bindingTypes() {
-    return bindings().stream().map(Binding::bindingType).collect(toImmutableSet());
-  }
-
-  /**
-   * The contribution type for these bindings.
-   *
-   * @throws IllegalStateException if there is not exactly one element in {@link
-   *     #contributionBindings()}, which will never happen for contributions in valid graphs
-   */
-  @Override
-  public ContributionType contributionType() {
-    return contributionBinding().contributionType();
-  }
-
-  /**
-   * The scope associated with the single binding.
-   *
-   * @throws IllegalStateException if {@link #bindings()} does not have exactly one element
-   */
-  Optional<Scope> scope() {
-    return binding().scope();
-  }
-}
diff --git a/java/dagger/internal/codegen/Scopes.java b/java/dagger/internal/codegen/Scopes.java
deleted file mode 100644
index 252f712..0000000
--- a/java/dagger/internal/codegen/Scopes.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DiagnosticFormatting.stripCommonTypePrefixes;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.common.collect.ImmutableSet;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.model.Scope;
-import dagger.producers.ProductionScope;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import javax.inject.Singleton;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/** Common names and convenience methods for {@link Scope}s. */
-final class Scopes {
-  /**
-   * Creates a {@link Scope} object from the {@link javax.inject.Scope}-annotated annotation type.
-   */
-  static Scope scope(TypeElement scopeType) {
-    return Scope.scope(SimpleAnnotationMirror.of(scopeType));
-  }
-
-  /** Returns a representation for {@link ProductionScope @ProductionScope} scope. */
-  static Scope productionScope(DaggerElements elements) {
-    return scope(elements, ProductionScope.class);
-  }
-
-  /** Returns a representation for {@link Singleton @Singleton} scope. */
-  static Scope singletonScope(DaggerElements elements) {
-    return scope(elements, Singleton.class);
-  }
-
-  private static Scope scope(
-      DaggerElements elements, Class<? extends Annotation> scopeAnnotationClass) {
-    return scope(elements.getTypeElement(scopeAnnotationClass));
-  }
-
-  /**
-   * Returns at most one associated scoped annotation from the source code element, throwing an
-   * exception if there are more than one.
-   */
-  static Optional<Scope> uniqueScopeOf(Element element) {
-    // TODO(ronshapiro): Use MoreCollectors.toOptional() once we can use guava-jre
-    return Optional.ofNullable(getOnlyElement(scopesOf(element), null));
-  }
-
-  /**
-   * Returns the readable source representation (name with @ prefix) of the scope's annotation type.
-   *
-   * <p>It's readable source because it has had common package prefixes removed, e.g.
-   * {@code @javax.inject.Singleton} is returned as {@code @Singleton}.
-   */
-  static String getReadableSource(Scope scope) {
-    return stripCommonTypePrefixes(scope.toString());
-  }
-
-  /** Returns all of the associated scopes for a source code element. */
-  static ImmutableSet<Scope> scopesOf(Element element) {
-    return AnnotationMirrors.getAnnotatedAnnotations(element, javax.inject.Scope.class)
-        .stream()
-        .map(Scope::scope)
-        .collect(toImmutableSet());
-  }
-}
diff --git a/java/dagger/internal/codegen/SetBindingExpression.java b/java/dagger/internal/codegen/SetBindingExpression.java
deleted file mode 100644
index 5efb85f..0000000
--- a/java/dagger/internal/codegen/SetBindingExpression.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.BindingRequest.bindingRequest;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.common.collect.ImmutableSet;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.SetBuilder;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import java.util.Collections;
-import java.util.Optional;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** A binding expression for multibound sets. */
-final class SetBindingExpression extends MultibindingExpression {
-  private final ProvisionBinding binding;
-  private final BindingGraph graph;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  SetBindingExpression(
-      ResolvedBindings resolvedBindings,
-      ComponentImplementation componentImplementation,
-      BindingGraph graph,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      DaggerElements elements) {
-    super(resolvedBindings, componentImplementation);
-    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
-    this.graph = graph;
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.types = types;
-    this.elements = elements;
-  }
-
-  @Override
-  protected Expression buildDependencyExpression(ClassName requestingClass) {
-    Optional<CodeBlock> superMethodCall = superMethodCall();
-    // TODO(ronshapiro): We should also make an ImmutableSet version of SetFactory
-    boolean isImmutableSetAvailable = isImmutableSetAvailable();
-    // TODO(ronshapiro, gak): Use Sets.immutableEnumSet() if it's available?
-    if (isImmutableSetAvailable
-        && binding.dependencies().stream().allMatch(this::isSingleValue)
-        && !superMethodCall.isPresent()) {
-      return Expression.create(
-          immutableSetType(),
-          CodeBlock.builder()
-              .add("$T.", ImmutableSet.class)
-              .add(maybeTypeParameter(requestingClass))
-              .add(
-                  "of($L)",
-                  binding
-                      .dependencies()
-                      .stream()
-                      .map(dependency -> getContributionExpression(dependency, requestingClass))
-                      .collect(toParametersCodeBlock()))
-              .build());
-    }
-    switch (binding.dependencies().size()) {
-      case 0:
-        return collectionsStaticFactoryInvocation(requestingClass, CodeBlock.of("emptySet()"));
-      case 1:
-        {
-          DependencyRequest dependency = getOnlyElement(binding.dependencies());
-          CodeBlock contributionExpression = getContributionExpression(dependency, requestingClass);
-          if (isSingleValue(dependency)) {
-            return collectionsStaticFactoryInvocation(
-                requestingClass, CodeBlock.of("singleton($L)", contributionExpression));
-          } else if (isImmutableSetAvailable) {
-            return Expression.create(
-                immutableSetType(),
-                CodeBlock.builder()
-                    .add("$T.", ImmutableSet.class)
-                    .add(maybeTypeParameter(requestingClass))
-                    .add("copyOf($L)", contributionExpression)
-                    .build());
-          }
-        }
-        // fall through
-      default:
-        CodeBlock.Builder instantiation = CodeBlock.builder();
-        instantiation
-            .add("$T.", isImmutableSetAvailable ? ImmutableSet.class : SetBuilder.class)
-            .add(maybeTypeParameter(requestingClass));
-        if (isImmutableSetBuilderWithExpectedSizeAvailable()) {
-          instantiation.add("builderWithExpectedSize($L)", binding.dependencies().size());
-        } else if (isImmutableSetAvailable) {
-          instantiation.add("builder()");
-        } else {
-          instantiation.add("newSetBuilder($L)", binding.dependencies().size());
-        }
-        for (DependencyRequest dependency : getNewContributions(binding.dependencies())) {
-          String builderMethod = isSingleValue(dependency) ? "add" : "addAll";
-          instantiation.add(
-              ".$L($L)", builderMethod, getContributionExpression(dependency, requestingClass));
-        }
-        if (superMethodCall.isPresent()) {
-          instantiation.add(CodeBlock.of(".addAll($L)", superMethodCall.get()));
-        }
-        instantiation.add(".build()");
-        return Expression.create(
-            isImmutableSetAvailable ? immutableSetType() : binding.key().type(),
-            instantiation.build());
-    }
-  }
-
-  private DeclaredType immutableSetType() {
-    return types.getDeclaredType(
-        elements.getTypeElement(ImmutableSet.class), SetType.from(binding.key()).elementType());
-  }
-
-  private CodeBlock getContributionExpression(
-      DependencyRequest dependency, ClassName requestingClass) {
-    return componentBindingExpressions
-        .getDependencyExpression(bindingRequest(dependency), requestingClass)
-        .codeBlock();
-  }
-
-  private Expression collectionsStaticFactoryInvocation(
-      ClassName requestingClass, CodeBlock methodInvocation) {
-    return Expression.create(
-        binding.key().type(),
-        CodeBlock.builder()
-            .add("$T.", Collections.class)
-            .add(maybeTypeParameter(requestingClass))
-            .add(methodInvocation)
-            .build());
-  }
-
-  private CodeBlock maybeTypeParameter(ClassName requestingClass) {
-    TypeMirror elementType = SetType.from(binding.key()).elementType();
-    return isTypeAccessibleFrom(elementType, requestingClass.packageName())
-        ? CodeBlock.of("<$T>", elementType)
-        : CodeBlock.of("");
-  }
-
-  private boolean isSingleValue(DependencyRequest dependency) {
-    return graph
-        .contributionBindings()
-        .get(dependency.key())
-        .contributionBinding()
-        .contributionType()
-        .equals(ContributionType.SET);
-  }
-
-  private boolean isImmutableSetBuilderWithExpectedSizeAvailable() {
-    if (isImmutableSetAvailable()) {
-      return methodsIn(elements.getTypeElement(ImmutableSet.class).getEnclosedElements())
-          .stream()
-          .anyMatch(method -> method.getSimpleName().contentEquals("builderWithExpectedSize"));
-    }
-    return false;
-  }
-
-  private boolean isImmutableSetAvailable() {
-    return elements.getTypeElement(ImmutableSet.class) != null;
-  }
-}
diff --git a/java/dagger/internal/codegen/SetFactoryCreationExpression.java b/java/dagger/internal/codegen/SetFactoryCreationExpression.java
deleted file mode 100644
index 9712091..0000000
--- a/java/dagger/internal/codegen/SetFactoryCreationExpression.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2015 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.checkNotNull;
-import static dagger.internal.codegen.SourceFiles.setFactoryClassName;
-
-import com.squareup.javapoet.CodeBlock;
-import dagger.model.DependencyRequest;
-import dagger.producers.Produced;
-import java.util.Optional;
-
-/** A factory creation expression for a multibound set. */
-final class SetFactoryCreationExpression extends MultibindingFactoryCreationExpression {
-
-  private final ComponentImplementation componentImplementation;
-  private final BindingGraph graph;
-  private final ContributionBinding binding;
-
-  SetFactoryCreationExpression(
-      ContributionBinding binding,
-      ComponentImplementation componentImplementation,
-      ComponentBindingExpressions componentBindingExpressions,
-      BindingGraph graph) {
-    super(binding, componentImplementation, componentBindingExpressions);
-    this.binding = checkNotNull(binding);
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.graph = checkNotNull(graph);
-  }
-
-  @Override
-  public CodeBlock creationExpression() {
-    CodeBlock.Builder builder = CodeBlock.builder().add("$T.", setFactoryClassName(binding));
-    if (!useRawType()) {
-      SetType setType = SetType.from(binding.key());
-      builder.add(
-          "<$T>",
-          setType.elementsAreTypeOf(Produced.class)
-              ? setType.unwrappedElementType(Produced.class)
-              : setType.elementType());
-    }
-
-    int individualProviders = 0;
-    int setProviders = 0;
-    CodeBlock.Builder builderMethodCalls = CodeBlock.builder();
-    String methodNameSuffix =
-        binding.bindingType().equals(BindingType.PROVISION) ? "Provider" : "Producer";
-
-    Optional<CodeBlock> superContributions = superContributions();
-    if (superContributions.isPresent()) {
-      // TODO(b/117833324): consider decomposing the Provider<Set<Provider>> and adding the
-      // individual contributions separately from the collection contributions. Though this may
-      // actually not be doable/desirable if the super provider instance is a DelegateFactory or
-      // another internal type that is not SetFactory
-      builderMethodCalls.add(".addCollection$N($L)", methodNameSuffix, superContributions.get());
-      setProviders++;
-    }
-
-    for (DependencyRequest dependency : dependenciesToImplement()) {
-      ContributionType contributionType =
-          graph.contributionBindings().get(dependency.key()).contributionType();
-      String methodNamePrefix;
-      switch (contributionType) {
-        case SET:
-          individualProviders++;
-          methodNamePrefix = "add";
-          break;
-        case SET_VALUES:
-          setProviders++;
-          methodNamePrefix = "addCollection";
-          break;
-        default:
-          throw new AssertionError(dependency + " is not a set multibinding");
-      }
-
-      builderMethodCalls.add(
-          ".$N$N($L)",
-          methodNamePrefix,
-          methodNameSuffix,
-          multibindingDependencyExpression(dependency));
-    }
-    builder.add("builder($L, $L)", individualProviders, setProviders);
-    builder.add(builderMethodCalls.build());
-
-    componentImplementation.registerImplementedMultibinding(binding, bindingRequest());
-
-    return builder.add(".build()").build();
-  }
-}
diff --git a/java/dagger/internal/codegen/SetType.java b/java/dagger/internal/codegen/SetType.java
deleted file mode 100644
index e4fa584..0000000
--- a/java/dagger/internal/codegen/SetType.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import dagger.model.Key;
-import java.util.Set;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Information about a {@link Set} {@link TypeMirror}.
- */
-@AutoValue
-abstract class SetType {
-  /**
-   * The set type itself, wrapped using {@link MoreTypes#equivalence()}. Use
-   * {@link #declaredSetType()} instead.
-   */
-  protected abstract Equivalence.Wrapper<DeclaredType> wrappedDeclaredSetType();
-  
-  /**
-   * The set type itself.
-   */
-  DeclaredType declaredSetType() {
-    return wrappedDeclaredSetType().get();
-  }
-
-  /**
-   * {@code true} if the set type is the raw {@link Set} type.
-   */
-  boolean isRawType() {
-    return declaredSetType().getTypeArguments().isEmpty();
-  }
-
-  /**
-   * The element type.
-   */
-  TypeMirror elementType() {
-    return declaredSetType().getTypeArguments().get(0);
-  }
-
-  /**
-   * {@code true} if {@link #elementType()} is a {@code clazz}.
-   */
-  boolean elementsAreTypeOf(Class<?> clazz) {
-    return MoreTypes.isType(elementType()) && MoreTypes.isTypeOf(clazz, elementType());
-  }
-
-  /**
-   * {@code T} if {@link #elementType()} is a {@code WrappingClass<T>}.
-   *
-   * @throws IllegalStateException if {@link #elementType()} is not a {@code WrappingClass<T>}
-   * @throws IllegalArgumentException if {@code wrappingClass} does not have exactly one type
-   *     parameter
-   */
-  TypeMirror unwrappedElementType(Class<?> wrappingClass) {
-    checkArgument(
-        wrappingClass.getTypeParameters().length == 1,
-        "%s must have exactly one type parameter",
-        wrappingClass);
-    checkArgument(
-        elementsAreTypeOf(wrappingClass),
-        "expected elements to be %s, but this type is %s",
-        wrappingClass,
-        declaredSetType());
-    return MoreTypes.asDeclared(elementType()).getTypeArguments().get(0);
-  }
-
-  /**
-   * {@code true} if {@code type} is a {@link Set} type.
-   */
-  static boolean isSet(TypeMirror type) {
-    return MoreTypes.isType(type) && MoreTypes.isTypeOf(Set.class, type);
-  }
-
-  /**
-   * {@code true} if {@code key.type()} is a {@link Set} type.
-   */
-  static boolean isSet(Key key) {
-    return isSet(key.type());
-  }
-
-  /**
-   * Returns a {@link SetType} for {@code type}.
-   *
-   * @throws IllegalArgumentException if {@code type} is not a {@link Set} type
-   */
-  static SetType from(TypeMirror type) {
-    checkArgument(isSet(type), "%s must be a Set", type);
-    return new AutoValue_SetType(MoreTypes.equivalence().wrap(MoreTypes.asDeclared(type)));
-  }
-
-  /**
-   * Returns a {@link SetType} for {@code key}'s {@link Key#type() type}.
-   *
-   * @throws IllegalArgumentException if {@code key.type()} is not a {@link Set} type
-   */
-  static SetType from(Key key) {
-    return from (key.type());
-  }
-}
diff --git a/java/dagger/internal/codegen/SimpleAnnotationMirror.java b/java/dagger/internal/codegen/SimpleAnnotationMirror.java
deleted file mode 100644
index 505c8ea..0000000
--- a/java/dagger/internal/codegen/SimpleAnnotationMirror.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2016 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 javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.base.Functions;
-import com.google.common.base.Joiner;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-
-/** A representation of an annotation. */
-final class SimpleAnnotationMirror implements AnnotationMirror {
-  private final TypeElement annotationType;
-  private final ImmutableMap<String, ? extends AnnotationValue> namedValues;
-  private final ImmutableMap<ExecutableElement, ? extends AnnotationValue> elementValues;
-
-  private SimpleAnnotationMirror(
-      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {
-    checkArgument(
-        annotationType.getKind().equals(ElementKind.ANNOTATION_TYPE),
-        "annotationType must be an annotation: %s",
-        annotationType);
-    checkArgument(
-        FluentIterable.from(methodsIn(annotationType.getEnclosedElements()))
-            .transform(element -> element.getSimpleName().toString())
-            .toSet()
-            .equals(namedValues.keySet()),
-        "namedValues must have values for exactly the members in %s: %s",
-        annotationType,
-        namedValues);
-    this.annotationType = annotationType;
-    this.namedValues = ImmutableMap.copyOf(namedValues);
-    this.elementValues =
-        Maps.toMap(
-            methodsIn(annotationType.getEnclosedElements()),
-            Functions.compose(
-                Functions.forMap(namedValues), element -> element.getSimpleName().toString()));
-  }
-
-  @Override
-  public DeclaredType getAnnotationType() {
-    return MoreTypes.asDeclared(annotationType.asType());
-  }
-
-  @Override
-  public Map<ExecutableElement, ? extends AnnotationValue> getElementValues() {
-    return elementValues;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder("@").append(annotationType.getQualifiedName());
-    if (!namedValues.isEmpty()) {
-      builder
-          .append('(')
-          .append(Joiner.on(", ").withKeyValueSeparator(" = ").join(namedValues))
-          .append(')');
-    }
-    return builder.toString();
-  }
-
-  /**
-   * An object representing an annotation instance.
-   *
-   * @param annotationType must be an annotation type with no members
-   */
-  static AnnotationMirror of(TypeElement annotationType) {
-    return of(annotationType, ImmutableMap.<String, AnnotationValue>of());
-  }
-
-  /**
-   * An object representing an annotation instance.
-   *
-   * @param annotationType must be an annotation type
-   * @param namedValues a value for every annotation member, including those with defaults, indexed
-   *     by simple name
-   */
-  static AnnotationMirror of(
-      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {
-    return new SimpleAnnotationMirror(annotationType, namedValues);
-  }
-}
diff --git a/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java b/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java
deleted file mode 100644
index 909d7ae..0000000
--- a/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.checkNotNull;
-
-/** A simple binding expression for instance requests. Does not scope. */
-abstract class SimpleInvocationBindingExpression extends BindingExpression {
-  // TODO(dpb): Take ContributionBinding instead of ResolvedBindings.
-  private final ResolvedBindings resolvedBindings;
-
-  SimpleInvocationBindingExpression(ResolvedBindings resolvedBindings) {
-    this.resolvedBindings = checkNotNull(resolvedBindings);
-  }
-
-  @Override
-  boolean requiresMethodEncapsulation() {
-    return !resolvedBindings.contributionBinding().dependencies().isEmpty();
-  }
-}
diff --git a/java/dagger/internal/codegen/SimpleMethodBindingExpression.java b/java/dagger/internal/codegen/SimpleMethodBindingExpression.java
deleted file mode 100644
index 805ac7b..0000000
--- a/java/dagger/internal/codegen/SimpleMethodBindingExpression.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.MoreElements.asExecutable;
-import static com.google.common.base.Preconditions.checkArgument;
-import static dagger.internal.codegen.InjectionMethods.ProvisionMethod.requiresInjectionMethod;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName;
-import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeName;
-import dagger.internal.codegen.InjectionMethods.ProvisionMethod;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.DependencyRequest;
-import java.util.Optional;
-import java.util.function.Function;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A binding expression that invokes methods or constructors directly (without attempting to scope)
- * {@link dagger.model.RequestKind#INSTANCE} requests.
- */
-final class SimpleMethodBindingExpression extends SimpleInvocationBindingExpression {
-  private final CompilerOptions compilerOptions;
-  private final ProvisionBinding provisionBinding;
-  private final ComponentBindingExpressions componentBindingExpressions;
-  private final MembersInjectionMethods membersInjectionMethods;
-  private final ComponentRequirementExpressions componentRequirementExpressions;
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-  private final SourceVersion sourceVersion;
-
-  SimpleMethodBindingExpression(
-      ResolvedBindings resolvedBindings,
-      CompilerOptions compilerOptions,
-      ComponentBindingExpressions componentBindingExpressions,
-      MembersInjectionMethods membersInjectionMethods,
-      ComponentRequirementExpressions componentRequirementExpressions,
-      DaggerTypes types,
-      DaggerElements elements,
-      SourceVersion sourceVersion) {
-    super(resolvedBindings);
-    this.compilerOptions = compilerOptions;
-    this.provisionBinding = (ProvisionBinding) resolvedBindings.contributionBinding();
-    checkArgument(
-        provisionBinding.implicitDependencies().isEmpty(),
-        "framework deps are not currently supported");
-    checkArgument(provisionBinding.bindingElement().isPresent());
-    this.componentBindingExpressions = componentBindingExpressions;
-    this.membersInjectionMethods = membersInjectionMethods;
-    this.componentRequirementExpressions = componentRequirementExpressions;
-    this.types = types;
-    this.elements = elements;
-    this.sourceVersion = sourceVersion;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    ImmutableMap<DependencyRequest, Expression> arguments =
-        ImmutableMap.copyOf(
-            Maps.asMap(
-                provisionBinding.dependencies(),
-                request -> dependencyArgument(request, requestingClass)));
-    Function<DependencyRequest, CodeBlock> argumentsFunction =
-        request -> arguments.get(request).codeBlock();
-    return requiresInjectionMethod(
-            provisionBinding,
-            arguments.values().asList(),
-            compilerOptions,
-            requestingClass.packageName(),
-            types)
-        ? invokeInjectionMethod(argumentsFunction, requestingClass)
-        : invokeMethod(argumentsFunction, requestingClass);
-  }
-
-  private Expression invokeMethod(
-      Function<DependencyRequest, CodeBlock> argumentsFunction,
-      ClassName requestingClass) {
-    // TODO(dpb): align this with the contents of InlineMethods.create
-    CodeBlock arguments =
-        provisionBinding.dependencies().stream()
-            .map(argumentsFunction)
-            .collect(toParametersCodeBlock());
-    ExecutableElement method = asExecutable(provisionBinding.bindingElement().get());
-    CodeBlock invocation;
-    switch (method.getKind()) {
-      case CONSTRUCTOR:
-        invocation = CodeBlock.of("new $T($L)", constructorTypeName(requestingClass), arguments);
-        break;
-      case METHOD:
-        CodeBlock module =
-            moduleReference(requestingClass)
-                .orElse(CodeBlock.of("$T", provisionBinding.bindingTypeElement().get()));
-        invocation = CodeBlock.of("$L.$L($L)", module, method.getSimpleName(), arguments);
-        break;
-      default:
-        throw new IllegalStateException();
-    }
-
-    return Expression.create(simpleMethodReturnType(), invocation);
-  }
-
-  private TypeName constructorTypeName(ClassName requestingClass) {
-    DeclaredType type = MoreTypes.asDeclared(provisionBinding.key().type());
-    TypeName typeName = TypeName.get(type);
-    if (type.getTypeArguments()
-        .stream()
-        .allMatch(t -> isTypeAccessibleFrom(t, requestingClass.packageName()))) {
-      return typeName;
-    }
-    return rawTypeName(typeName);
-  }
-
-  private Expression invokeInjectionMethod(
-      Function<DependencyRequest, CodeBlock> argumentsFunction, ClassName requestingClass) {
-    return injectMembers(
-        ProvisionMethod.invoke(
-            provisionBinding,
-            argumentsFunction,
-            requestingClass,
-            moduleReference(requestingClass),
-            compilerOptions,
-            elements));
-  }
-
-  private Expression dependencyArgument(DependencyRequest dependency, ClassName requestingClass) {
-    return componentBindingExpressions.getDependencyArgumentExpression(dependency, requestingClass);
-  }
-
-  private Expression injectMembers(CodeBlock instance) {
-    if (provisionBinding.injectionSites().isEmpty()) {
-      return Expression.create(simpleMethodReturnType(), instance);
-    }
-    if (sourceVersion.compareTo(SourceVersion.RELEASE_7) <= 0) {
-      // Java 7 type inference can't figure out that instance in
-      // injectParameterized(Parameterized_Factory.newParameterized()) is Parameterized<T> and not
-      // Parameterized<Object>
-      if (!MoreTypes.asDeclared(provisionBinding.key().type()).getTypeArguments().isEmpty()) {
-        TypeName keyType = TypeName.get(provisionBinding.key().type());
-        instance = CodeBlock.of("($T) ($T) $L", keyType, rawTypeName(keyType), instance);
-      }
-    }
-    MethodSpec membersInjectionMethod = membersInjectionMethods.getOrCreate(provisionBinding.key());
-    TypeMirror returnType =
-        membersInjectionMethod.returnType.equals(TypeName.OBJECT)
-            ? elements.getTypeElement(Object.class).asType()
-            : provisionBinding.key().type();
-    return Expression.create(returnType, CodeBlock.of("$N($L)", membersInjectionMethod, instance));
-  }
-
-  private Optional<CodeBlock> moduleReference(ClassName requestingClass) {
-    return provisionBinding.requiresModuleInstance()
-        ? provisionBinding
-            .contributingModule()
-            .map(Element::asType)
-            .map(ComponentRequirement::forModule)
-            .map(module -> componentRequirementExpressions.getExpression(module, requestingClass))
-        : Optional.empty();
-  }
-
-  private TypeMirror simpleMethodReturnType() {
-    return provisionBinding.contributedPrimitiveType().orElse(provisionBinding.key().type());
-  }
-}
diff --git a/java/dagger/internal/codegen/SimpleTypeAnnotationValue.java b/java/dagger/internal/codegen/SimpleTypeAnnotationValue.java
deleted file mode 100644
index 7f043db..0000000
--- a/java/dagger/internal/codegen/SimpleTypeAnnotationValue.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 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 javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.type.TypeMirror;
-
-/** An {@link AnnotationValue} that contains a {@link TypeMirror}. */
-final class SimpleTypeAnnotationValue implements AnnotationValue {
-  private final TypeMirror value;
-
-  SimpleTypeAnnotationValue(TypeMirror value) {
-    this.value = value;
-  }
-
-  @Override
-  public TypeMirror getValue() {
-    return value;
-  }
-
-  @Override
-  public String toString() {
-    return value + ".class";
-  }
-
-  @Override
-  public <R, P> R accept(AnnotationValueVisitor<R, P> visitor, P parameter) {
-    return visitor.visitType(getValue(), parameter);
-  }
-}
diff --git a/java/dagger/internal/codegen/SourceFileGenerationException.java b/java/dagger/internal/codegen/SourceFileGenerationException.java
deleted file mode 100644
index 07c1c68..0000000
--- a/java/dagger/internal/codegen/SourceFileGenerationException.java
+++ /dev/null
@@ -1,54 +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.checkNotNull;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.squareup.javapoet.ClassName;
-import java.util.Optional;
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.Element;
-
-/**
- * An exception thrown to indicate that a source file could not be generated.
- *
- * <p>This exception <b>should not</b> be used to report detectable, logical errors as it may mask
- * other errors that might have been caught upon further processing. Use a {@link ValidationReport}
- * for that.
- */
-final class SourceFileGenerationException extends Exception {
-  private final Element associatedElement;
-
-  SourceFileGenerationException(
-      Optional<ClassName> generatedClassName, Throwable cause, Element associatedElement) {
-    super(createMessage(generatedClassName, cause.getMessage()), cause);
-    this.associatedElement = checkNotNull(associatedElement);
-  }
-
-  private static String createMessage(Optional<ClassName> generatedClassName, String message) {
-    return String.format("Could not generate %s: %s.",
-        generatedClassName.isPresent()
-            ? generatedClassName.get()
-            : "unknown file",
-        message);
-  }
-
-  void printMessageTo(Messager messager) {
-    messager.printMessage(ERROR, getMessage(), associatedElement);
-  }
-}
diff --git a/java/dagger/internal/codegen/SourceFileGenerator.java b/java/dagger/internal/codegen/SourceFileGenerator.java
deleted file mode 100644
index 7dddc2f..0000000
--- a/java/dagger/internal/codegen/SourceFileGenerator.java
+++ /dev/null
@@ -1,124 +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.auto.common.GeneratedAnnotations.generatedAnnotation;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Throwables;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.TypeSpec;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Optional;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-
-/**
- * A template class that provides a framework for properly handling IO while generating source files
- * from an annotation processor.  Particularly, it makes a best effort to ensure that files that
- * fail to write successfully are deleted.
- *
- * @param <T> The input type from which source is to be generated.
- */
-abstract class SourceFileGenerator<T> {
-  private static final String GENERATED_COMMENTS = "https://dagger.dev";
-
-  private final Filer filer;
-  private final DaggerElements elements;
-  private final SourceVersion sourceVersion;
-
-  SourceFileGenerator(Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-    this.filer = checkNotNull(filer);
-    this.elements = checkNotNull(elements);
-    this.sourceVersion = checkNotNull(sourceVersion);
-  }
-
-  SourceFileGenerator(SourceFileGenerator<T> delegate) {
-    this(delegate.filer, delegate.elements, delegate.sourceVersion);
-  }
-
-  /**
-   * Generates a source file to be compiled for {@code T}. Writes any generation exception to {@code
-   * messager} and does not throw.
-   */
-  void generate(T input, Messager messager) {
-    try {
-      generate(input);
-    } catch (SourceFileGenerationException e) {
-      e.printMessageTo(messager);
-    }
-  }
-
-  /** Generates a source file to be compiled for {@code T}. */
-  void generate(T input) throws SourceFileGenerationException {
-    ClassName generatedTypeName = nameGeneratedType(input);
-    Optional<TypeSpec.Builder> type = write(generatedTypeName, input);
-    if (!type.isPresent()) {
-      return;
-    }
-    try {
-      buildJavaFile(generatedTypeName, input, type.get()).writeTo(filer);
-    } catch (Exception e) {
-      // if the code above threw a SFGE, use that
-      Throwables.propagateIfPossible(e, SourceFileGenerationException.class);
-      // otherwise, throw a new one
-      throw new SourceFileGenerationException(
-          Optional.empty(), e, originatingElement(input));
-    }
-  }
-
-  private JavaFile buildJavaFile(
-      ClassName generatedTypeName, T input, TypeSpec.Builder typeSpecBuilder) {
-    typeSpecBuilder.addOriginatingElement(originatingElement(input));
-    Optional<AnnotationSpec> generatedAnnotation =
-        generatedAnnotation(elements, sourceVersion)
-            .map(
-                annotation ->
-                    AnnotationSpec.builder(ClassName.get(annotation))
-                        .addMember("value", "$S", "dagger.internal.codegen.ComponentProcessor")
-                        .addMember("comments", "$S", GENERATED_COMMENTS)
-                        .build());
-    generatedAnnotation.ifPresent(typeSpecBuilder::addAnnotation);
-    JavaFile.Builder javaFileBuilder =
-        JavaFile.builder(generatedTypeName.packageName(), typeSpecBuilder.build())
-            .skipJavaLangImports(true);
-    if (!generatedAnnotation.isPresent()) {
-      javaFileBuilder.addFileComment("Generated by Dagger ($L).", GENERATED_COMMENTS);
-    }
-    return javaFileBuilder.build();
-  }
-
-  /**
-   * Implementations should return the {@link ClassName} for the top-level type to be generated.
-   */
-  abstract ClassName nameGeneratedType(T input);
-
-  /** Returns the originating element of the generating type. */
-  abstract Element originatingElement(T input);
-
-  /**
-   * Returns a {@link TypeSpec.Builder type} to be generated for {@code T}, or {@link
-   * Optional#empty()} if no file should be generated.
-   */
-  // TODO(ronshapiro): write() makes more sense in JavaWriter where all writers are mutable.
-  // consider renaming to something like typeBuilder() which conveys the mutability of the result
-  abstract Optional<TypeSpec.Builder> write(ClassName generatedTypeName, T input);
-}
diff --git a/java/dagger/internal/codegen/SourceFileGeneratorsModule.java b/java/dagger/internal/codegen/SourceFileGeneratorsModule.java
deleted file mode 100644
index c32262a..0000000
--- a/java/dagger/internal/codegen/SourceFileGeneratorsModule.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.SourceFileGeneratorsModule.ComponentModule;
-import dagger.internal.codegen.SourceFileGeneratorsModule.MembersInjectionModule;
-import dagger.internal.codegen.SourceFileGeneratorsModule.ProductionModule;
-import dagger.internal.codegen.SourceFileGeneratorsModule.ProvisionModule;
-import javax.lang.model.element.TypeElement;
-
-@Module(
-    includes = {
-      ProvisionModule.class,
-      ProductionModule.class,
-      MembersInjectionModule.class,
-      ComponentModule.class
-    })
-interface SourceFileGeneratorsModule {
-  @Module
-  abstract class GeneratorModule<T, G extends SourceFileGenerator<T>> {
-    @Provides
-    SourceFileGenerator<T> generator(G generator, CompilerOptions compilerOptions) {
-      return compilerOptions.headerCompilation()
-          ? HjarSourceFileGenerator.wrap(generator)
-          : generator;
-    }
-  }
-
-  @Module
-  class ProvisionModule extends GeneratorModule<ProvisionBinding, FactoryGenerator> {}
-
-  @Module
-  class ProductionModule extends GeneratorModule<ProductionBinding, ProducerFactoryGenerator> {}
-
-  @Module
-  class MembersInjectionModule
-      extends GeneratorModule<MembersInjectionBinding, MembersInjectorGenerator> {}
-
-  @Module
-  class ComponentModule extends GeneratorModule<BindingGraph, ComponentGenerator> {}
-
-  // the abstract module is not available because we're using a qualifier
-  @Provides
-  @ModuleGenerator
-  static SourceFileGenerator<TypeElement> generator(
-      ModuleConstructorProxyGenerator generator, CompilerOptions compilerOptions) {
-    return compilerOptions.headerCompilation()
-        ? HjarSourceFileGenerator.wrap(generator)
-        : generator;
-  }
-}
diff --git a/java/dagger/internal/codegen/SourceFiles.java b/java/dagger/internal/codegen/SourceFiles.java
deleted file mode 100644
index fd93d0d..0000000
--- a/java/dagger/internal/codegen/SourceFiles.java
+++ /dev/null
@@ -1,348 +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.CaseFormat.LOWER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Verify.verify;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.Optionals.optionalComparator;
-import static dagger.internal.codegen.javapoet.TypeNames.DOUBLE_CHECK;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCED_PRODUCER;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCER_PRODUCER;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_PRODUCER;
-import static dagger.internal.codegen.javapoet.TypeNames.MAP_PROVIDER_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER_OF_LAZY;
-import static dagger.internal.codegen.javapoet.TypeNames.SET_FACTORY;
-import static dagger.internal.codegen.javapoet.TypeNames.SET_OF_PRODUCED_PRODUCER;
-import static dagger.internal.codegen.javapoet.TypeNames.SET_PRODUCER;
-import static dagger.model.BindingKind.INJECTION;
-import static dagger.model.BindingKind.MULTIBOUND_MAP;
-import static dagger.model.BindingKind.MULTIBOUND_SET;
-import static java.util.Comparator.comparing;
-import static javax.lang.model.SourceVersion.isName;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.base.CaseFormat;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.internal.SetFactory;
-import dagger.model.DependencyRequest;
-import dagger.model.Key;
-import dagger.model.RequestKind;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.internal.SetOfProducedProducer;
-import dagger.producers.internal.SetProducer;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import javax.inject.Provider;
-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.TypeParameterElement;
-
-/**
- * Utilities for generating files.
- */
-class SourceFiles {
-
-  private static final Joiner CLASS_FILE_NAME_JOINER = Joiner.on('_');
-
-  /**
-   * Sorts {@link DependencyRequest} instances in an order likely to reflect their logical
-   * importance.
-   */
-  static final Comparator<DependencyRequest> DEPENDENCY_ORDERING =
-      // put fields before parameters
-      comparing(
-              (DependencyRequest request) -> request.requestElement().map(Element::getKind),
-              optionalComparator())
-          // order by dependency kind
-          .thenComparing(DependencyRequest::kind)
-          // then sort by name
-          .thenComparing(
-              request ->
-                  request.requestElement().map(element -> element.getSimpleName().toString()),
-              optionalComparator());
-
-  /**
-   * Generates names and keys for the factory class fields needed to hold the framework classes for
-   * all of the dependencies of {@code binding}. It is responsible for choosing a name that
-   *
-   * <ul>
-   * <li>represents all of the dependency requests for this key
-   * <li>is <i>probably</i> associated with the type being bound
-   * <li>is unique within the class
-   * </ul>
-   *
-   * @param binding must be an unresolved binding (type parameters must match its type element's)
-   */
-  static ImmutableMap<Key, FrameworkField> generateBindingFieldsForDependencies(
-      Binding binding) {
-    checkArgument(!binding.unresolved().isPresent(), "binding must be unresolved: %s", binding);
-
-    ImmutableMap.Builder<Key, FrameworkField> bindingFields = ImmutableMap.builder();
-    for (Binding.DependencyAssociation dependencyAssociation : binding.dependencyAssociations()) {
-      FrameworkDependency frameworkDependency = dependencyAssociation.frameworkDependency();
-      bindingFields.put(
-          frameworkDependency.key(),
-          FrameworkField.create(
-              ClassName.get(frameworkDependency.frameworkClass()),
-              TypeName.get(frameworkDependency.key().type()),
-              fieldNameForDependency(dependencyAssociation.dependencyRequests())));
-    }
-    return bindingFields.build();
-  }
-
-  private static String fieldNameForDependency(ImmutableSet<DependencyRequest> dependencyRequests) {
-    // collect together all of the names that we would want to call the provider
-    ImmutableSet<String> dependencyNames =
-        dependencyRequests.stream().map(DependencyVariableNamer::name).collect(toImmutableSet());
-
-    if (dependencyNames.size() == 1) {
-      // if there's only one name, great! use it!
-      return Iterables.getOnlyElement(dependencyNames);
-    } else {
-      // in the event that a field is being used for a bunch of deps with different names,
-      // add all the names together with "And"s in the middle. E.g.: stringAndS
-      Iterator<String> namesIterator = dependencyNames.iterator();
-      String first = namesIterator.next();
-      StringBuilder compositeNameBuilder = new StringBuilder(first);
-      while (namesIterator.hasNext()) {
-        compositeNameBuilder
-            .append("And")
-            .append(CaseFormat.LOWER_CAMEL.to(UPPER_CAMEL, namesIterator.next()));
-      }
-      return compositeNameBuilder.toString();
-    }
-  }
-
-  static CodeBlock frameworkTypeUsageStatement(
-      CodeBlock frameworkTypeMemberSelect, RequestKind dependencyKind) {
-    switch (dependencyKind) {
-      case LAZY:
-        return CodeBlock.of("$T.lazy($L)", DOUBLE_CHECK, frameworkTypeMemberSelect);
-      case INSTANCE:
-      case FUTURE:
-        return CodeBlock.of("$L.get()", frameworkTypeMemberSelect);
-      case PROVIDER:
-      case PRODUCER:
-        return frameworkTypeMemberSelect;
-      case PROVIDER_OF_LAZY:
-        return CodeBlock.of("$T.create($L)", PROVIDER_OF_LAZY, frameworkTypeMemberSelect);
-      default: // including PRODUCED
-        throw new AssertionError(dependencyKind);
-    }
-  }
-
-  /**
-   * Returns a mapping of {@link DependencyRequest}s to {@link CodeBlock}s that {@linkplain
-   * #frameworkTypeUsageStatement(CodeBlock, RequestKind) use them}.
-   */
-  static ImmutableMap<DependencyRequest, CodeBlock> frameworkFieldUsages(
-      ImmutableSet<DependencyRequest> dependencies, ImmutableMap<Key, FieldSpec> fields) {
-    return Maps.toMap(
-        dependencies,
-        dep ->
-            frameworkTypeUsageStatement(CodeBlock.of("$N", fields.get(dep.key())), dep.kind()));
-  }
-
-  /**
-   * Returns the generated factory or members injector name for a binding.
-   */
-  static ClassName generatedClassNameForBinding(Binding binding) {
-    switch (binding.bindingType()) {
-      case PROVISION:
-      case PRODUCTION:
-        ContributionBinding contribution = (ContributionBinding) binding;
-        switch (contribution.kind()) {
-          case INJECTION:
-          case PROVISION:
-          case PRODUCTION:
-            return elementBasedClassName(
-                MoreElements.asExecutable(binding.bindingElement().get()), "Factory");
-
-          default:
-            throw new AssertionError();
-        }
-
-      case MEMBERS_INJECTION:
-        return membersInjectorNameForType(
-            ((MembersInjectionBinding) binding).membersInjectedType());
-    }
-    throw new AssertionError();
-  }
-
-  /**
-   * Calculates an appropriate {@link ClassName} for a generated class that is based on {@code
-   * element}, appending {@code suffix} at the end.
-   *
-   * <p>This will always return a {@linkplain ClassName#topLevelClassName() top level class name},
-   * even if {@code element}'s enclosing class is a nested type.
-   */
-  static ClassName elementBasedClassName(ExecutableElement element, String suffix) {
-    ClassName enclosingClassName =
-        ClassName.get(MoreElements.asType(element.getEnclosingElement()));
-    String methodName =
-        element.getKind().equals(ElementKind.CONSTRUCTOR)
-            ? ""
-            : LOWER_CAMEL.to(UPPER_CAMEL, element.getSimpleName().toString());
-    return ClassName.get(
-        enclosingClassName.packageName(),
-        classFileName(enclosingClassName) + "_" + methodName + suffix);
-  }
-
-  static TypeName parameterizedGeneratedTypeNameForBinding(Binding binding) {
-    ClassName className = generatedClassNameForBinding(binding);
-    ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding);
-    return typeParameters.isEmpty()
-        ? className
-        : ParameterizedTypeName.get(className, Iterables.toArray(typeParameters, TypeName.class));
-  }
-
-  static ClassName membersInjectorNameForType(TypeElement typeElement) {
-    return siblingClassName(typeElement,  "_MembersInjector");
-  }
-
-  static String classFileName(ClassName className) {
-    return CLASS_FILE_NAME_JOINER.join(className.simpleNames());
-  }
-
-  static ClassName generatedMonitoringModuleName(
-      TypeElement componentElement) {
-    return siblingClassName(componentElement, "_MonitoringModule");
-  }
-
-  // TODO(ronshapiro): when JavaPoet migration is complete, replace the duplicated code
-  // which could use this.
-  private static ClassName siblingClassName(TypeElement typeElement, String suffix) {
-    ClassName className = ClassName.get(typeElement);
-    return className.topLevelClassName().peerClass(classFileName(className) + suffix);
-  }
-
-  /**
-   * The {@link java.util.Set} factory class name appropriate for set bindings.
-   *
-   * <ul>
-   * <li>{@link SetFactory} for provision bindings.
-   * <li>{@link SetProducer} for production bindings for {@code Set<T>}.
-   * <li>{@link SetOfProducedProducer} for production bindings for {@code Set<Produced<T>>}.
-   * </ul>
-   */
-  static ClassName setFactoryClassName(ContributionBinding binding) {
-    checkArgument(binding.kind().equals(MULTIBOUND_SET));
-    if (binding.bindingType().equals(BindingType.PROVISION)) {
-      return SET_FACTORY;
-    } else {
-      SetType setType = SetType.from(binding.key());
-      return setType.elementsAreTypeOf(Produced.class) ? SET_OF_PRODUCED_PRODUCER : SET_PRODUCER;
-    }
-  }
-
-  /** The {@link java.util.Map} factory class name appropriate for map bindings. */
-  static ClassName mapFactoryClassName(ContributionBinding binding) {
-    checkState(binding.kind().equals(MULTIBOUND_MAP), binding.kind());
-    MapType mapType = MapType.from(binding.key());
-    switch (binding.bindingType()) {
-      case PROVISION:
-        return mapType.valuesAreTypeOf(Provider.class) ? MAP_PROVIDER_FACTORY : MAP_FACTORY;
-      case PRODUCTION:
-        return mapType.valuesAreFrameworkType()
-            ? mapType.valuesAreTypeOf(Producer.class)
-                ? MAP_OF_PRODUCER_PRODUCER
-                : MAP_OF_PRODUCED_PRODUCER
-            : MAP_PRODUCER;
-      default:
-        throw new IllegalArgumentException(binding.bindingType().toString());
-    }
-  }
-
-  static ImmutableList<TypeVariableName> bindingTypeElementTypeVariableNames(Binding binding) {
-    if (binding instanceof ContributionBinding) {
-      ContributionBinding contributionBinding = (ContributionBinding) binding;
-      if (!contributionBinding.kind().equals(INJECTION)
-          && !contributionBinding.requiresModuleInstance()) {
-        return ImmutableList.of();
-      }
-    }
-    List<? extends TypeParameterElement> typeParameters =
-        binding.bindingTypeElement().get().getTypeParameters();
-    return typeParameters.stream().map(TypeVariableName::get).collect(toImmutableList());
-  }
-
-  /**
-   * Returns a name to be used for variables of the given {@linkplain TypeElement type}. Prefer
-   * semantically meaningful variable names, but if none can be derived, this will produce something
-   * readable.
-   */
-  // TODO(gak): maybe this should be a function of TypeMirrors instead of Elements?
-  static String simpleVariableName(TypeElement typeElement) {
-    String candidateName = UPPER_CAMEL.to(LOWER_CAMEL, typeElement.getSimpleName().toString());
-    String variableName = protectAgainstKeywords(candidateName);
-    verify(isName(variableName), "'%s' was expected to be a valid variable name");
-    return variableName;
-  }
-
-  static String protectAgainstKeywords(String candidateName) {
-    switch (candidateName) {
-      case "package":
-        return "pkg";
-      case "boolean":
-        return "b";
-      case "double":
-        return "d";
-      case "byte":
-        return "b";
-      case "int":
-        return "i";
-      case "short":
-        return "s";
-      case "char":
-        return "c";
-      case "void":
-        return "v";
-      case "class":
-        return "clazz";
-      case "float":
-        return "f";
-      case "long":
-        return "l";
-      default:
-        return SourceVersion.isKeyword(candidateName) ? candidateName + '_' : candidateName;
-    }
-  }
-
-  private SourceFiles() {}
-}
diff --git a/java/dagger/internal/codegen/SpiModule.java b/java/dagger/internal/codegen/SpiModule.java
deleted file mode 100644
index a8f13e1..0000000
--- a/java/dagger/internal/codegen/SpiModule.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.Module;
-import dagger.Provides;
-import dagger.spi.BindingGraphPlugin;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.util.Optional;
-import java.util.ServiceLoader;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-
-/** Contains the bindings for {@link BindingGraphValidator} from external SPI providers. */
-@Module
-abstract class SpiModule {
-  private SpiModule() {}
-
-  @Provides
-  @Singleton
-  static ImmutableSet<BindingGraphPlugin> externalPlugins(
-      @TestingPlugins Optional<ImmutableSet<BindingGraphPlugin>> testingPlugins) {
-    return testingPlugins.orElseGet(
-        () ->
-            ImmutableSet.copyOf(
-                ServiceLoader.load(
-                    BindingGraphPlugin.class, BindingGraphValidator.class.getClassLoader())));
-  }
-
-  @Qualifier
-  @Retention(RUNTIME)
-  @Target({FIELD, PARAMETER, METHOD})
-  @interface TestingPlugins {}
-}
diff --git a/java/dagger/internal/codegen/SubcomponentCreatorBindingEdgeImpl.java b/java/dagger/internal/codegen/SubcomponentCreatorBindingEdgeImpl.java
deleted file mode 100644
index c97024e..0000000
--- a/java/dagger/internal/codegen/SubcomponentCreatorBindingEdgeImpl.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.collect.Iterables.getOnlyElement;
-import static dagger.internal.codegen.DaggerStreams.presentValues;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static java.util.stream.Collectors.joining;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.model.BindingGraph.SubcomponentCreatorBindingEdge;
-import javax.lang.model.element.TypeElement;
-
-/** An implementation of {@link SubcomponentCreatorBindingEdge}. */
-final class SubcomponentCreatorBindingEdgeImpl implements SubcomponentCreatorBindingEdge {
-
-  private final ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations;
-
-  SubcomponentCreatorBindingEdgeImpl(
-      ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) {
-    this.subcomponentDeclarations = subcomponentDeclarations;
-  }
-
-  @Override
-  public ImmutableSet<TypeElement> declaringModules() {
-    return subcomponentDeclarations.stream()
-        .map(SubcomponentDeclaration::contributingModule)
-        .flatMap(presentValues())
-        .collect(toImmutableSet());
-  }
-
-  @Override
-  public String toString() {
-    return "subcomponent declared by "
-        + (subcomponentDeclarations.size() == 1
-            ? getOnlyElement(declaringModules()).getQualifiedName()
-            : declaringModules().stream()
-                .map(TypeElement::getQualifiedName)
-                .collect(joining(", ", "{", "}")));
-  }
-}
diff --git a/java/dagger/internal/codegen/SubcomponentCreatorBindingExpression.java b/java/dagger/internal/codegen/SubcomponentCreatorBindingExpression.java
deleted file mode 100644
index b415d3f..0000000
--- a/java/dagger/internal/codegen/SubcomponentCreatorBindingExpression.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.squareup.javapoet.ClassName;
-import dagger.internal.codegen.javapoet.Expression;
-import javax.lang.model.type.TypeMirror;
-
-/** A binding expression for a subcomponent creator that just invokes the constructor. */
-final class SubcomponentCreatorBindingExpression extends SimpleInvocationBindingExpression {
-  private final TypeMirror creatorType;
-  private final String creatorImplementationName;
-
-  SubcomponentCreatorBindingExpression(
-      ResolvedBindings resolvedBindings, String creatorImplementationName) {
-    super(resolvedBindings);
-    this.creatorType = resolvedBindings.key().type();
-    this.creatorImplementationName = creatorImplementationName;
-  }
-
-  @Override
-  Expression getDependencyExpression(ClassName requestingClass) {
-    return Expression.create(creatorType, "new $L()", creatorImplementationName);
-  }
-}
diff --git a/java/dagger/internal/codegen/SubcomponentDeclaration.java b/java/dagger/internal/codegen/SubcomponentDeclaration.java
deleted file mode 100644
index 5677857..0000000
--- a/java/dagger/internal/codegen/SubcomponentDeclaration.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 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.auto.common.AnnotationMirrors.getAnnotationElementAndValue;
-import static dagger.internal.codegen.ConfigurationAnnotations.getSubcomponentCreator;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableSet;
-import dagger.model.Key;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A declaration for a subcomponent that is included in a module via {@link
- * dagger.Module#subcomponents()}.
- */
-@AutoValue
-abstract class SubcomponentDeclaration extends BindingDeclaration {
-  /**
-   * Key for the {@link dagger.Subcomponent.Builder} or {@link
-   * dagger.producers.ProductionSubcomponent.Builder} of {@link #subcomponentType()}.
-   */
-  @Override
-  public abstract Key key();
-
-  /**
-   * The type element that defines the {@link dagger.Subcomponent} or {@link
-   * dagger.producers.ProductionSubcomponent} for this declaration.
-   */
-  abstract TypeElement subcomponentType();
-
-  /** The module annotation. */
-  abstract ModuleAnnotation moduleAnnotation();
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-
-  static class Factory {
-    private final KeyFactory keyFactory;
-
-    @Inject
-    Factory(KeyFactory keyFactory) {
-      this.keyFactory = keyFactory;
-    }
-
-    ImmutableSet<SubcomponentDeclaration> forModule(TypeElement module) {
-      ImmutableSet.Builder<SubcomponentDeclaration> declarations = ImmutableSet.builder();
-      ModuleAnnotation moduleAnnotation = ModuleAnnotation.moduleAnnotation(module).get();
-      Element subcomponentAttribute =
-          getAnnotationElementAndValue(moduleAnnotation.annotation(), "subcomponents").getKey();
-      for (TypeElement subcomponent : moduleAnnotation.subcomponents()) {
-        declarations.add(
-            new AutoValue_SubcomponentDeclaration(
-                Optional.of(subcomponentAttribute),
-                Optional.of(module),
-                keyFactory.forSubcomponentCreator(
-                    getSubcomponentCreator(subcomponent).get().asType()),
-                subcomponent,
-                moduleAnnotation));
-      }
-      return declarations.build();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/SubcomponentFactoryMethodValidator.java b/java/dagger/internal/codegen/SubcomponentFactoryMethodValidator.java
deleted file mode 100644
index 0c6a006..0000000
--- a/java/dagger/internal/codegen/SubcomponentFactoryMethodValidator.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2018 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.auto.common.MoreTypes.asDeclared;
-import static com.google.auto.common.MoreTypes.asExecutable;
-import static com.google.auto.common.MoreTypes.asTypeElements;
-import static com.google.common.collect.Sets.union;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.Util.componentCanMakeNewInstances;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ChildFactoryMethodEdge;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-
-/** Reports an error if a subcomponent factory method is missing required modules. */
-final class SubcomponentFactoryMethodValidator implements BindingGraphPlugin {
-
-  private final DaggerTypes types;
-  private final Map<ComponentNode, Set<TypeElement>> inheritedModulesCache = new HashMap<>();
-
-  @Inject
-  SubcomponentFactoryMethodValidator(DaggerTypes types) {
-    this.types = types;
-  }
-
-  @Override
-  public String pluginName() {
-    return "Dagger/SubcomponentFactoryMethodMissingModule";
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    if (!bindingGraph.rootComponentNode().isRealComponent()
-        || bindingGraph.rootComponentNode().isSubcomponent()) {
-      // We don't know all the modules that might be owned by the child until we know the real root
-      // component, which we don't if the root component node is really a module or a subcomponent.
-      return;
-    }
-    bindingGraph.network().edges().stream()
-        .flatMap(instancesOf(ChildFactoryMethodEdge.class))
-        .forEach(
-            edge -> {
-              ImmutableSet<TypeElement> missingModules = findMissingModules(edge, bindingGraph);
-              if (!missingModules.isEmpty()) {
-                reportMissingModuleParameters(
-                    edge, missingModules, bindingGraph, diagnosticReporter);
-              }
-            });
-  }
-
-  private ImmutableSet<TypeElement> findMissingModules(
-      ChildFactoryMethodEdge edge, BindingGraph graph) {
-    ImmutableSet<TypeElement> factoryMethodParameters =
-        subgraphFactoryMethodParameters(edge, graph);
-    ComponentNode child = (ComponentNode) graph.network().incidentNodes(edge).target();
-    SetView<TypeElement> modulesOwnedByChild = ownedModules(child, graph);
-    return graph.bindings().stream()
-        // bindings owned by child
-        .filter(binding -> binding.componentPath().equals(child.componentPath()))
-        // that require a module instance
-        .filter(binding -> binding.requiresModuleInstance())
-        .map(binding -> binding.contributingModule().get())
-        .distinct()
-        // module owned by child
-        .filter(module -> modulesOwnedByChild.contains(module))
-        // module not in the method parameters
-        .filter(module -> !factoryMethodParameters.contains(module))
-        // module doesn't have an accessible no-arg constructor
-        .filter(moduleType -> !componentCanMakeNewInstances(moduleType))
-        .collect(toImmutableSet());
-  }
-
-  private ImmutableSet<TypeElement> subgraphFactoryMethodParameters(
-      ChildFactoryMethodEdge edge, BindingGraph bindingGraph) {
-    ComponentNode parent = (ComponentNode) bindingGraph.network().incidentNodes(edge).source();
-    DeclaredType parentType = asDeclared(parent.componentPath().currentComponent().asType());
-    ExecutableType factoryMethodType =
-        asExecutable(types.asMemberOf(parentType, edge.factoryMethod()));
-    return asTypeElements(factoryMethodType.getParameterTypes());
-  }
-
-  private SetView<TypeElement> ownedModules(ComponentNode component, BindingGraph graph) {
-    return Sets.difference(
-        ((ComponentNodeImpl) component).componentDescriptor().moduleTypes(),
-        inheritedModules(component, graph));
-  }
-
-  private Set<TypeElement> inheritedModules(ComponentNode component, BindingGraph graph) {
-    return Util.reentrantComputeIfAbsent(
-        inheritedModulesCache, component, uncachedInheritedModules(graph));
-  }
-
-  private Function<ComponentNode, Set<TypeElement>> uncachedInheritedModules(BindingGraph graph) {
-    return componentNode ->
-        componentNode.componentPath().atRoot()
-            ? ImmutableSet.of()
-            : graph
-                .componentNode(componentNode.componentPath().parent())
-                .map(parent -> union(ownedModules(parent, graph), inheritedModules(parent, graph)))
-                .get();
-  }
-
-  private void reportMissingModuleParameters(
-      ChildFactoryMethodEdge edge,
-      ImmutableSet<TypeElement> missingModules,
-      BindingGraph graph,
-      DiagnosticReporter diagnosticReporter) {
-    diagnosticReporter.reportSubcomponentFactoryMethod(
-        ERROR,
-        edge,
-        "%s requires modules which have no visible default constructors. "
-            + "Add the following modules as parameters to this method: %s",
-        graph
-            .network()
-            .incidentNodes(edge)
-            .target()
-            .componentPath()
-            .currentComponent()
-            .getQualifiedName(),
-        Joiner.on(", ").join(missingModules));
-  }
-}
diff --git a/java/dagger/internal/codegen/SubcomponentNames.java b/java/dagger/internal/codegen/SubcomponentNames.java
deleted file mode 100644
index f2ffd83..0000000
--- a/java/dagger/internal/codegen/SubcomponentNames.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.internal.codegen.DaggerStreams.toImmutableMap;
-import static java.lang.Character.isUpperCase;
-import static java.lang.String.format;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import dagger.model.Key;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Holds the unique simple names for all subcomponents, keyed by their {@link ComponentDescriptor}
- * and {@link Key} of the subcomponent builder.
- */
-final class SubcomponentNames {
-  private static final Splitter QUALIFIED_NAME_SPLITTER = Splitter.on('.');
-
-  private final ImmutableMap<ComponentDescriptor, String> namesByDescriptor;
-  private final ImmutableMap<Key, ComponentDescriptor> descriptorsByCreatorKey;
-
-  SubcomponentNames(BindingGraph graph, KeyFactory keyFactory) {
-    this.namesByDescriptor = namesByDescriptor(graph);
-    this.descriptorsByCreatorKey = descriptorsByCreatorKey(keyFactory, namesByDescriptor.keySet());
-  }
-
-  /** Returns the simple component name for the given {@link ComponentDescriptor}. */
-  String get(ComponentDescriptor componentDescriptor) {
-    return namesByDescriptor.get(componentDescriptor);
-  }
-
-  /**
-   * Returns the simple name for the subcomponent creator implementation with the given {@link Key}.
-   */
-  String getCreatorName(Key key) {
-    return getCreatorName(descriptorsByCreatorKey.get(key));
-  }
-
-  /**
-   * Returns the simple name for the subcomponent creator implementation for the given {@link
-   * ComponentDescriptor}.
-   */
-  String getCreatorName(ComponentDescriptor componentDescriptor) {
-    checkArgument(componentDescriptor.creatorDescriptor().isPresent());
-    ComponentCreatorDescriptor creatorDescriptor = componentDescriptor.creatorDescriptor().get();
-    return get(componentDescriptor) + creatorDescriptor.kind().typeName();
-  }
-
-  private static ImmutableMap<ComponentDescriptor, String> namesByDescriptor(BindingGraph graph) {
-    ImmutableListMultimap<String, ComponentDescriptor> componentDescriptorsBySimpleName =
-        Multimaps.index(
-            graph.componentDescriptors(),
-            componentDescriptor -> componentDescriptor.typeElement().getSimpleName().toString());
-    ImmutableMap<ComponentDescriptor, Namer> componentNamers =
-        qualifiedNames(graph.componentDescriptors());
-    Map<ComponentDescriptor, String> subcomponentImplSimpleNames = new LinkedHashMap<>();
-    componentDescriptorsBySimpleName
-        .asMap()
-        .values()
-        .forEach(
-            components ->
-                subcomponentImplSimpleNames.putAll(
-                    disambiguateConflictingSimpleNames(components, componentNamers)));
-    subcomponentImplSimpleNames.remove(graph.componentDescriptor());
-    return ImmutableMap.copyOf(subcomponentImplSimpleNames);
-  }
-
-  private static ImmutableMap<Key, ComponentDescriptor> descriptorsByCreatorKey(
-      KeyFactory keyFactory, ImmutableSet<ComponentDescriptor> subcomponents) {
-    return subcomponents.stream()
-        .filter(subcomponent -> subcomponent.creatorDescriptor().isPresent())
-        .collect(
-            toImmutableMap(
-                subcomponent ->
-                    keyFactory.forSubcomponentCreator(
-                        subcomponent.creatorDescriptor().get().typeElement().asType()),
-                subcomponent -> subcomponent));
-  }
-
-  private static ImmutableBiMap<ComponentDescriptor, String> disambiguateConflictingSimpleNames(
-      Collection<ComponentDescriptor> components,
-      ImmutableMap<ComponentDescriptor, Namer> componentNamers) {
-    Map<String, ComponentDescriptor> generatedSimpleNames = new LinkedHashMap<>();
-
-    // Let's see if we can get away with using simpleName() everywhere.
-    for (ComponentDescriptor component : components) {
-      Namer namer = componentNamers.get(component);
-      if (generatedSimpleNames.containsKey(namer.simpleName())) {
-        break;
-      }
-      generatedSimpleNames.put(namer.simpleName(), component);
-    }
-
-    if (generatedSimpleNames.size() != components.size()) {
-      // Simple approach didn't work out, let's use more complicated names.
-      // We keep them small to fix https://github.com/google/dagger/issues/421.
-      generatedSimpleNames.clear();
-      UniqueNameSet nameSet = new UniqueNameSet();
-      for (ComponentDescriptor component : components) {
-        Namer namer = componentNamers.get(component);
-        String simpleName = namer.simpleName();
-        String basePrefix = namer.uniquingPrefix();
-        generatedSimpleNames.put(
-            format("%s_%s", nameSet.getUniqueName(basePrefix), simpleName), component);
-      }
-    }
-    return ImmutableBiMap.copyOf(generatedSimpleNames).inverse();
-  }
-
-  private static ImmutableMap<ComponentDescriptor, Namer> qualifiedNames(
-      Iterable<ComponentDescriptor> componentDescriptors) {
-    ImmutableMap.Builder<ComponentDescriptor, Namer> builder = ImmutableMap.builder();
-    for (ComponentDescriptor component : componentDescriptors) {
-      builder.put(component, new Namer(component.typeElement()));
-    }
-    return builder.build();
-  }
-
-  private static final class Namer {
-    final TypeElement typeElement;
-
-    Namer(TypeElement typeElement) {
-      this.typeElement = typeElement;
-    }
-
-    String simpleName() {
-      return typeElement.getSimpleName().toString();
-    }
-
-    /** Returns a prefix that could make {@link #simpleName()} more unique. */
-    String uniquingPrefix() {
-      String containerName = typeElement.getEnclosingElement().getSimpleName().toString();
-
-      // If parent element looks like a class, use its initials as a prefix.
-      if (!containerName.isEmpty() && isUpperCase(containerName.charAt(0))) {
-        return CharMatcher.javaLowerCase().removeFrom(containerName);
-      }
-
-      // Not in a normally named class. Prefix with the initials of the elements leading here.
-      Name qualifiedName = typeElement.getQualifiedName();
-      Iterator<String> pieces = QUALIFIED_NAME_SPLITTER.split(qualifiedName).iterator();
-      StringBuilder b = new StringBuilder();
-
-      while (pieces.hasNext()) {
-        String next = pieces.next();
-        if (pieces.hasNext()) {
-          b.append(next.charAt(0));
-        }
-      }
-
-      // Note that a top level class in the root package will be prefixed "$_".
-      return b.length() > 0 ? b.toString() : "$";
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/SwitchingProviders.java b/java/dagger/internal/codegen/SwitchingProviders.java
deleted file mode 100644
index 29633d9..0000000
--- a/java/dagger/internal/codegen/SwitchingProviders.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-import static com.google.common.collect.Iterables.getLast;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.DaggerStreams.toImmutableList;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
-import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.PUBLIC;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.TypeVariableName;
-import dagger.internal.codegen.javapoet.CodeBlocks;
-import dagger.internal.codegen.javapoet.Expression;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Keeps track of all provider expression requests for a component.
- *
- * <p>The provider expression request will be satisfied by a single generated {@code Provider} inner
- * class that can provide instances for all types by switching on an id.
- */
-// TODO(ronshapiro): either merge this with InnerSwitchingProviders, or repurpose this for
-// SwitchingProducers
-abstract class SwitchingProviders {
-  /**
-   * Defines the {@linkplain Expression expressions} for a switch case in a {@code SwitchProvider}
-   * for a particular binding.
-   */
-  // TODO(user): Consider handling SwitchingProviders with dependency arguments in this class,
-  // then we wouldn't need the getProviderExpression method.
-  // TODO(user): Consider making this an abstract class with equals/hashCode defined by the key
-  // and then using this class directly in Map types instead of Key.
-  interface SwitchCase {
-    /** Returns the {@link Key} for this switch case. */
-    Key key();
-
-    /** Returns the {@link Expression} that returns the provided instance for this case. */
-    Expression getReturnExpression(ClassName switchingProviderClass);
-
-    /**
-     * Returns the {@link Expression} that returns the {@code SwitchProvider} instance for this
-     * case.
-     */
-    Expression getProviderExpression(ClassName switchingProviderClass, int switchId);
-  }
-
-  /**
-   * Each switch size is fixed at 100 cases each and put in its own method. This is to limit the
-   * size of the methods so that we don't reach the "huge" method size limit for Android that will
-   * prevent it from being AOT compiled in some versions of Android (b/77652521). This generally
-   * starts to happen around 1500 cases, but we are choosing 100 to be safe.
-   */
-  // TODO(user): Include a proguard_spec in the Dagger library to prevent inlining these methods?
-  // TODO(ronshapiro): Consider making this configurable via a flag.
-  private static final int MAX_CASES_PER_SWITCH = 100;
-
-  private static final long MAX_CASES_PER_CLASS = MAX_CASES_PER_SWITCH * MAX_CASES_PER_SWITCH;
-  private static final TypeVariableName T = TypeVariableName.get("T");
-
-  /**
-   * Maps a {@link Key} to an instance of a {@link SwitchingProviderBuilder}. Each group of {@code
-   * MAX_CASES_PER_CLASS} keys will share the same instance.
-   */
-  private final Map<Key, SwitchingProviderBuilder> switchingProviderBuilders =
-      new LinkedHashMap<>();
-
-  private final ComponentImplementation componentImplementation;
-  private final ClassName owningComponent;
-  private final DaggerTypes types;
-  private final UniqueNameSet switchingProviderNames = new UniqueNameSet();
-
-  SwitchingProviders(ComponentImplementation componentImplementation, DaggerTypes types) {
-    this.componentImplementation = checkNotNull(componentImplementation);
-    this.types = checkNotNull(types);
-    this.owningComponent = checkNotNull(componentImplementation).name();
-  }
-
-  /** Returns the {@link TypeSpec} for a {@code SwitchingProvider} based on the given builder. */
-  protected abstract TypeSpec createSwitchingProviderType(TypeSpec.Builder builder);
-
-  /**
-   * Returns the {@link Expression} that returns the {@code SwitchProvider} instance for the case.
-   */
-  protected final Expression getProviderExpression(SwitchCase switchCase) {
-    return switchingProviderBuilders
-        .computeIfAbsent(switchCase.key(), key -> getSwitchingProviderBuilder())
-        .getProviderExpression(switchCase);
-  }
-
-  private SwitchingProviderBuilder getSwitchingProviderBuilder() {
-    if (switchingProviderBuilders.size() % MAX_CASES_PER_CLASS == 0) {
-      String name = switchingProviderNames.getUniqueName("SwitchingProvider");
-      SwitchingProviderBuilder switchingProviderBuilder =
-          new SwitchingProviderBuilder(owningComponent.nestedClass(name));
-      componentImplementation.addSwitchingProvider(switchingProviderBuilder::build);
-      return switchingProviderBuilder;
-    }
-    return getLast(switchingProviderBuilders.values());
-  }
-
-  // TODO(user): Consider just merging this class with SwitchingProviders.
-  private final class SwitchingProviderBuilder {
-    // Keep the switch cases ordered by switch id. The switch Ids are assigned in pre-order
-    // traversal, but the switch cases are assigned in post-order traversal of the binding graph.
-    private final Map<Integer, CodeBlock> switchCases = new TreeMap<>();
-    private final Map<Key, Integer> switchIds = new HashMap<>();
-    private final ClassName switchingProviderType;
-
-    SwitchingProviderBuilder(ClassName switchingProviderType) {
-      this.switchingProviderType = checkNotNull(switchingProviderType);
-    }
-
-    Expression getProviderExpression(SwitchCase switchCase) {
-      Key key = switchCase.key();
-      if (!switchIds.containsKey(key)) {
-        int switchId = switchIds.size();
-        switchIds.put(key, switchId);
-        switchCases.put(switchId, createSwitchCaseCodeBlock(switchCase));
-      }
-      return switchCase.getProviderExpression(switchingProviderType, switchIds.get(key));
-    }
-
-    private CodeBlock createSwitchCaseCodeBlock(SwitchCase switchCase) {
-      CodeBlock instanceCodeBlock =
-          switchCase.getReturnExpression(switchingProviderType).box(types).codeBlock();
-
-      return CodeBlock.builder()
-          // TODO(user): Is there something else more useful than the key?
-          .add("case $L: // $L \n", switchIds.get(switchCase.key()), switchCase.key())
-          .addStatement("return ($T) $L", T, instanceCodeBlock)
-          .build();
-    }
-
-    private TypeSpec build() {
-      return createSwitchingProviderType(
-          classBuilder(switchingProviderType)
-              .addTypeVariable(T)
-              .addSuperinterface(providerOf(T))
-              .addMethods(getMethods()));
-    }
-
-    private ImmutableList<MethodSpec> getMethods() {
-      ImmutableList<CodeBlock> switchCodeBlockPartitions = switchCodeBlockPartitions();
-      if (switchCodeBlockPartitions.size() == 1) {
-        // There are less than MAX_CASES_PER_SWITCH cases, so no need for extra get methods.
-        return ImmutableList.of(
-            methodBuilder("get")
-                .addModifiers(PUBLIC)
-                .addAnnotation(suppressWarnings(UNCHECKED))
-                .addAnnotation(Override.class)
-                .returns(T)
-                .addCode(getOnlyElement(switchCodeBlockPartitions))
-                .build());
-      }
-
-      // This is the main public "get" method that will route to private getter methods.
-      MethodSpec.Builder routerMethod =
-          methodBuilder("get")
-              .addModifiers(PUBLIC)
-              .addAnnotation(Override.class)
-              .returns(T)
-              .beginControlFlow("switch (id / $L)", MAX_CASES_PER_SWITCH);
-
-      ImmutableList.Builder<MethodSpec> getMethods = ImmutableList.builder();
-      for (int i = 0; i < switchCodeBlockPartitions.size(); i++) {
-        MethodSpec method =
-            methodBuilder("get" + i)
-                .addModifiers(PRIVATE)
-                .addAnnotation(suppressWarnings(UNCHECKED))
-                .returns(T)
-                .addCode(switchCodeBlockPartitions.get(i))
-                .build();
-        getMethods.add(method);
-        routerMethod.addStatement("case $L: return $N()", i, method);
-      }
-
-      routerMethod.addStatement("default: throw new $T(id)", AssertionError.class).endControlFlow();
-
-      return getMethods.add(routerMethod.build()).build();
-    }
-
-    private ImmutableList<CodeBlock> switchCodeBlockPartitions() {
-      return Lists.partition(ImmutableList.copyOf(switchCases.values()), MAX_CASES_PER_SWITCH)
-          .stream()
-          .map(
-              partitionCases ->
-                  CodeBlock.builder()
-                      .beginControlFlow("switch (id)")
-                      .add(CodeBlocks.concat(partitionCases))
-                      .addStatement("default: throw new $T(id)", AssertionError.class)
-                      .endControlFlow()
-                      .build())
-          .collect(toImmutableList());
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/SystemComponentsModule.java b/java/dagger/internal/codegen/SystemComponentsModule.java
deleted file mode 100644
index 3f59b24..0000000
--- a/java/dagger/internal/codegen/SystemComponentsModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.base.Ticker;
-import dagger.Module;
-import dagger.Provides;
-
-/** Module to provide system-level dependencies (such as time-related objects). */
-@Module
-interface SystemComponentsModule {
-
-  @Provides
-  static Ticker ticker() {
-    return Ticker.systemTicker();
-  }
-}
diff --git a/java/dagger/internal/codegen/TopLevel.java b/java/dagger/internal/codegen/TopLevel.java
deleted file mode 100644
index 4f456f2..0000000
--- a/java/dagger/internal/codegen/TopLevel.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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 java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * A {@link Qualifier} for bindings that are associated with the top level component implementation.
- */
-@Retention(RUNTIME)
-@Qualifier
-@interface TopLevel {}
diff --git a/java/dagger/internal/codegen/TopLevelImplementationComponent.java b/java/dagger/internal/codegen/TopLevelImplementationComponent.java
deleted file mode 100644
index 306c05d..0000000
--- a/java/dagger/internal/codegen/TopLevelImplementationComponent.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.BindsInstance;
-import dagger.Module;
-import dagger.Subcomponent;
-
-/**
- * A shared subcomponent for a top-level {@link ComponentImplementation} and any nested child
- * implementations.
- */
-@PerGeneratedFile
-@Subcomponent
-interface TopLevelImplementationComponent {
-  CurrentImplementationSubcomponent.Builder currentImplementationSubcomponentBuilder();
-
-  @Subcomponent.Builder
-  interface Builder {
-    @BindsInstance
-    Builder topLevelComponent(@TopLevel ComponentImplementation topLevelImplementation);
-    TopLevelImplementationComponent build();
-  }
-
-  @Module(subcomponents = TopLevelImplementationComponent.class)
-  interface InstallationModule {}
-}
diff --git a/java/dagger/internal/codegen/TypeCheckingProcessingStep.java b/java/dagger/internal/codegen/TypeCheckingProcessingStep.java
deleted file mode 100644
index 00769b2..0000000
--- a/java/dagger/internal/codegen/TypeCheckingProcessingStep.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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.checkNotNull;
-
-import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.SetMultimap;
-import java.lang.annotation.Annotation;
-import java.util.function.Function;
-import javax.lang.model.element.Element;
-
-/**
- * A {@link ProcessingStep} that processes one element at a time and defers any for which {@link
- * TypeNotPresentException} is thrown.
- */
-// TODO(dpb): Contribute to auto-common.
-abstract class TypeCheckingProcessingStep<E extends Element> implements ProcessingStep {
-  private final Function<Element, E> downcaster;
-
-  TypeCheckingProcessingStep(Function<Element, E> downcaster) {
-    this.downcaster = checkNotNull(downcaster);
-  }
-
-  @Override
-  public ImmutableSet<Element> process(
-      SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
-    ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder();
-    ImmutableSetMultimap.copyOf(elementsByAnnotation)
-        .inverse()
-        .asMap()
-        .forEach(
-            (element, annotations) -> {
-              try {
-                process(downcaster.apply(element), ImmutableSet.copyOf(annotations));
-              } catch (TypeNotPresentException e) {
-                deferredElements.add(element);
-              }
-            });
-    return deferredElements.build();
-  }
-
-  /**
-   * Processes one element. If this method throws {@link TypeNotPresentException}, the element will
-   * be deferred until the next round of processing.
-   *
-   * @param annotations the subset of {@link ProcessingStep#annotations()} that annotate {@code
-   *     element}
-   */
-  protected abstract void process(E element, ImmutableSet<Class<? extends Annotation>> annotations);
-}
diff --git a/java/dagger/internal/codegen/TypeProtoConverter.java b/java/dagger/internal/codegen/TypeProtoConverter.java
deleted file mode 100644
index c703bd8..0000000
--- a/java/dagger/internal/codegen/TypeProtoConverter.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 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 javax.lang.model.util.ElementFilter.typesIn;
-
-import com.google.auto.common.MoreTypes;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.internal.codegen.serialization.TypeProto;
-import dagger.internal.codegen.serialization.TypeProto.PrimitiveKind;
-import javax.inject.Inject;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.WildcardType;
-
-/** Converts {@link TypeMirror}s to {@link TypeProto}s and vice-versa. */
-final class TypeProtoConverter {
-  // TODO(ronshapiro): if DaggerTypes and DaggerElements become public, move this file to
-  // dagger.internal.codegen.serialization
-  private final DaggerTypes types;
-  private final DaggerElements elements;
-
-  @Inject
-  TypeProtoConverter(DaggerTypes types, DaggerElements elements) {
-    this.types = types;
-    this.elements = elements;
-  }
-
-  /** Translates a {@link TypeMirror} to a proto representation. */
-  static TypeProto toProto(TypeMirror type) {
-    TypeProto.Builder builder = TypeProto.newBuilder();
-    int arrayDimensions = 0;
-    while (type.getKind().equals(TypeKind.ARRAY)) {
-      type = MoreTypes.asArray(type).getComponentType();
-      arrayDimensions++;
-    }
-    builder.setArrayDimensions(arrayDimensions);
-    if (type.getKind().isPrimitive()) {
-      builder.setPrimitiveKind(PrimitiveKind.valueOf(type.getKind().name()));
-    } else if (type.getKind().equals(TypeKind.WILDCARD)) {
-      WildcardType wildcardType = MoreTypes.asWildcard(type);
-      TypeProto.Wildcard.Builder wildcardBuilder = TypeProto.Wildcard.newBuilder();
-      if (wildcardType.getExtendsBound() != null) {
-        wildcardBuilder.setExtendsBound(toProto(wildcardType.getExtendsBound()));
-      } else if (wildcardType.getSuperBound() != null) {
-        wildcardBuilder.setSuperBound(toProto(wildcardType.getSuperBound()));
-      }
-      builder.setWildcard(wildcardBuilder);
-    } else {
-      TypeElement typeElement = MoreTypes.asTypeElement(type);
-      DeclaredType declaredType = MoreTypes.asDeclared(type);
-      TypeMirror enclosingType = declaredType.getEnclosingType();
-      if (enclosingType.getKind().equals(TypeKind.NONE)) {
-        builder.setQualifiedName(typeElement.getQualifiedName().toString());
-      } else {
-        builder
-            .setEnclosingType(toProto(enclosingType))
-            .setSimpleName(typeElement.getSimpleName().toString());
-      }
-      declaredType.getTypeArguments().stream()
-          .map(TypeProtoConverter::toProto)
-          .forEachOrdered(builder::addTypeArguments);
-    }
-    return builder.build();
-  }
-
-  /** Creates an {@link TypeMirror} from its proto representation. */
-  TypeMirror fromProto(TypeProto type) {
-    if (type.hasWildcard()) {
-      return wildcardType(type.getWildcard());
-    }
-
-    TypeMirror[] typeArguments =
-        type.getTypeArgumentsList().stream().map(this::fromProto).toArray(TypeMirror[]::new);
-    TypeMirror typeMirror;
-    if (!type.getPrimitiveKind().equals(PrimitiveKind.UNKNOWN)) {
-      typeMirror = types.getPrimitiveType(TypeKind.valueOf(type.getPrimitiveKind().name()));
-    } else if (type.hasEnclosingType()) {
-      DeclaredType enclosingType = MoreTypes.asDeclared(fromProto(type.getEnclosingType()));
-      TypeElement typeElement =
-          typesIn(enclosingType.asElement().getEnclosedElements()).stream()
-              .filter(inner -> inner.getSimpleName().contentEquals(type.getSimpleName()))
-              .findFirst()
-              .get();
-      typeMirror = types.getDeclaredType(enclosingType, typeElement, typeArguments);
-    } else {
-      typeMirror =
-          types.getDeclaredType(elements.getTypeElement(type.getQualifiedName()), typeArguments);
-    }
-    for (int i = 0; i < type.getArrayDimensions(); i++) {
-      typeMirror = types.getArrayType(typeMirror);
-    }
-    return typeMirror;
-  }
-
-  private TypeMirror wildcardType(TypeProto.Wildcard wildcard) {
-    if (wildcard.hasExtendsBound()) {
-      return types.getWildcardType(fromProto(wildcard.getExtendsBound()), null);
-    } else if (wildcard.hasSuperBound()) {
-      return types.getWildcardType(null, fromProto(wildcard.getSuperBound()));
-    } else {
-      return types.getWildcardType(null, null);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/UniqueNameSet.java b/java/dagger/internal/codegen/UniqueNameSet.java
deleted file mode 100644
index 11c48b3..0000000
--- a/java/dagger/internal/codegen/UniqueNameSet.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 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 java.util.HashSet;
-import java.util.Set;
-
-/** A collector for names to be used in the same namespace that should not conflict. */
-final class UniqueNameSet {
-  private final Set<String> uniqueNames = new HashSet<>();
-
-  /**
-   * Generates a unique name using {@code base}. If {@code base} has not yet been added, it will be
-   * returned as-is. If your {@code base} is healthy, this will always return {@code base}.
-   */
-  String getUniqueName(CharSequence base) {
-    String name = base.toString();
-    for (int differentiator = 2; !uniqueNames.add(name); differentiator++) {
-      name = base.toString() + differentiator;
-    }
-    return name;
-  }
-
-  /**
-   * Adds {@code name} without any modification to the name set. Has no effect if {@code name} is
-   * already present in the set.
-   */
-  void claim(CharSequence name) {
-    uniqueNames.add(name.toString());
-  }
-}
diff --git a/java/dagger/internal/codegen/UnwrappedMapKeyGenerator.java b/java/dagger/internal/codegen/UnwrappedMapKeyGenerator.java
deleted file mode 100644
index 2b7b02c..0000000
--- a/java/dagger/internal/codegen/UnwrappedMapKeyGenerator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.MapKey;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Generates classes that create annotation instances for an unwrapped {@link MapKey} annotation
- * type whose nested value is an annotation. The generated class will have a private empty
- * constructor and a static method that creates each annotation type that is nested in the top-level
- * annotation type.
- *
- * <p>So for an example {@link MapKey} annotation:
- *
- * <pre>
- *   {@literal @MapKey}(unwrapValue = true)
- *   {@literal @interface} Foo {
- *     Bar bar();
- *   }
- *
- *   {@literal @interface} Bar {
- *     {@literal Class<?> baz();}
- *   }
- * </pre>
- *
- * the generated class will look like:
- *
- * <pre>
- *   public final class FooCreator {
- *     private FooCreator() {}
- *
- *     public static Bar createBar({@literal Class<?> baz}) { … }
- *   }
- * </pre>
- */
-final class UnwrappedMapKeyGenerator extends AnnotationCreatorGenerator {
-
-  @Inject
-  UnwrappedMapKeyGenerator(Filer filer, DaggerElements elements, SourceVersion sourceVersion) {
-    super(filer, elements, sourceVersion);
-  }
-
-  @Override
-  protected Set<TypeElement> annotationsToCreate(TypeElement annotationElement) {
-    Set<TypeElement> nestedAnnotationElements = super.annotationsToCreate(annotationElement);
-    nestedAnnotationElements.remove(annotationElement);
-    return nestedAnnotationElements;
-  }
-}
diff --git a/java/dagger/internal/codegen/Util.java b/java/dagger/internal/codegen/Util.java
deleted file mode 100644
index 1869b7c..0000000
--- a/java/dagger/internal/codegen/Util.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2013 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 javax.lang.model.element.ElementKind.CONSTRUCTOR;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.STATIC;
-
-import java.util.Map;
-import java.util.function.Function;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Utilities for handling types in annotation processors
- */
-final class Util {
-  /**
-   * Returns true if and only if a component can instantiate new instances (typically of a module)
-   * rather than requiring that they be passed.
-   */
-  static boolean componentCanMakeNewInstances(TypeElement typeElement) {
-    switch (typeElement.getKind()) {
-      case CLASS:
-        break;
-      case ENUM:
-      case ANNOTATION_TYPE:
-      case INTERFACE:
-        return false;
-      default:
-        throw new AssertionError("TypeElement cannot have kind: " + typeElement.getKind());
-    }
-
-    if (typeElement.getModifiers().contains(ABSTRACT)) {
-      return false;
-    }
-
-    if (requiresEnclosingInstance(typeElement)) {
-      return false;
-    }
-
-    for (Element enclosed : typeElement.getEnclosedElements()) {
-      if (enclosed.getKind().equals(CONSTRUCTOR)
-          && ((ExecutableElement) enclosed).getParameters().isEmpty()
-          && !enclosed.getModifiers().contains(PRIVATE)) {
-        return true;
-      }
-    }
-
-    // TODO(gak): still need checks for visibility
-
-    return false;
-  }
-
-  private static boolean requiresEnclosingInstance(TypeElement typeElement) {
-    switch (typeElement.getNestingKind()) {
-      case TOP_LEVEL:
-        return false;
-      case MEMBER:
-        return !typeElement.getModifiers().contains(STATIC);
-      case ANONYMOUS:
-      case LOCAL:
-        return true;
-    }
-    throw new AssertionError(
-        "TypeElement cannot have nesting kind: " + typeElement.getNestingKind());
-  }
-
-  /**
-   * A version of {@link Map#computeIfAbsent(Object, Function)} that allows {@code mappingFunction}
-   * to update {@code map}.
-   */
-  static <K, V> V reentrantComputeIfAbsent(
-      Map<K, V> map, K key, Function<? super K, ? extends V> mappingFunction) {
-    V value = map.get(key);
-    if (value == null) {
-      value = mappingFunction.apply(key);
-      if (value != null) {
-        map.put(key, value);
-      }
-    }
-    return value;
-  }
-
-  private Util() {}
-}
diff --git a/java/dagger/internal/codegen/Validation.java b/java/dagger/internal/codegen/Validation.java
deleted file mode 100644
index f6a4b3f..0000000
--- a/java/dagger/internal/codegen/Validation.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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 java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import javax.inject.Qualifier;
-
-/**
- * Qualifier annotation for the {@link dagger.spi.BindingGraphPlugin}s that are used to implement
- * core Dagger validation.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Qualifier
-@interface Validation {}
diff --git a/java/dagger/internal/codegen/ValidationReport.java b/java/dagger/internal/codegen/ValidationReport.java
deleted file mode 100644
index d7c3252..0000000
--- a/java/dagger/internal/codegen/ValidationReport.java
+++ /dev/null
@@ -1,288 +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 dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.ElementFormatter.elementToString;
-import static javax.tools.Diagnostic.Kind.ERROR;
-import static javax.tools.Diagnostic.Kind.NOTE;
-import static javax.tools.Diagnostic.Kind.WARNING;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.graph.Traverser;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import java.util.Optional;
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.tools.Diagnostic;
-import javax.tools.Diagnostic.Kind;
-
-/** A collection of issues to report for source code. */
-@AutoValue
-abstract class ValidationReport<T extends Element> {
-
-  /**
-   * The subject of the report. Should be an element within a compilation unit being processed by
-   * this compilation task.
-   */
-  abstract T subject();
-
-  /** The items to report for the {@linkplain #subject() subject}. */
-  abstract ImmutableSet<Item> items();
-
-  /** Returns the {@link #items()} from this report and all transitive subreports. */
-  ImmutableSet<Item> allItems() {
-    return allReports()
-        .stream()
-        .flatMap(report -> report.items().stream())
-        .collect(toImmutableSet());
-  }
-
-  /** Other reports associated with this one. */
-  abstract ImmutableSet<ValidationReport<?>> subreports();
-
-  private static final Traverser<ValidationReport<?>> SUBREPORTS =
-      Traverser.forTree(ValidationReport::subreports);
-
-  /** Returns this report and all transitive subreports. */
-  ImmutableSet<ValidationReport<?>> allReports() {
-    return ImmutableSet.copyOf(SUBREPORTS.depthFirstPreOrder(this));
-  }
-
-  /**
-   * {@code true} if {@link #isClean()} should return {@code false} even if there are no error items
-   * in this report.
-   */
-  abstract boolean markedDirty();
-
-  /**
-   * Returns {@code true} if there are no errors in this report or any subreports and {@link
-   * #markedDirty()} is {@code false}.
-   */
-  boolean isClean() {
-    if (markedDirty()) {
-      return false;
-    }
-    for (Item item : items()) {
-      switch (item.kind()) {
-        case ERROR:
-          return false;
-        default:
-          break;
-      }
-    }
-    for (ValidationReport<?> subreport : subreports()) {
-      if (!subreport.isClean()) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Prints all {@linkplain #items() messages} to {@code messager} (and recurs for subreports). If a
-   * message's {@linkplain Item#element() element} is contained within the report's {@linkplain
-   * #subject() subject}, associates the message with the message's element. Otherwise, since
-   * {@link Diagnostic} reporting is expected to be associated with elements that are currently
-   * being compiled, associates the message with the subject itself and prepends a reference to the
-   * item's element.
-   */
-  void printMessagesTo(Messager messager) {
-    for (Item item : items()) {
-      if (isEnclosedIn(subject(), item.element())) {
-        if (item.annotation().isPresent()) {
-          if (item.annotationValue().isPresent()) {
-            messager.printMessage(
-                item.kind(),
-                item.message(),
-                item.element(),
-                item.annotation().get(),
-                item.annotationValue().get());
-          } else {
-            messager.printMessage(
-                item.kind(), item.message(), item.element(), item.annotation().get());
-          }
-        } else {
-          messager.printMessage(item.kind(), item.message(), item.element());
-        }
-      } else {
-        String message = String.format("[%s] %s", elementToString(item.element()), item.message());
-        messager.printMessage(item.kind(), message, subject());
-      }
-    }
-    for (ValidationReport<?> subreport : subreports()) {
-      subreport.printMessagesTo(messager);
-    }
-  }
-
-  private static boolean isEnclosedIn(Element parent, Element child) {
-    Element current = child;
-    while (current != null) {
-      if (current.equals(parent)) {
-        return true;
-      }
-      current = current.getEnclosingElement();
-    }
-    return false;
-  }
-
-  @AutoValue
-  static abstract class Item {
-    abstract String message();
-    abstract Kind kind();
-    abstract Element element();
-    abstract Optional<AnnotationMirror> annotation();
-    abstract Optional<AnnotationValue> annotationValue();
-  }
-
-  static <T extends Element> Builder<T> about(T subject) {
-    return new Builder<>(subject);
-  }
-
-  @CanIgnoreReturnValue
-  static final class Builder<T extends Element> {
-    private final T subject;
-    private final ImmutableSet.Builder<Item> items = ImmutableSet.builder();
-    private final ImmutableSet.Builder<ValidationReport<?>> subreports = ImmutableSet.builder();
-    private boolean markedDirty;
-
-    private Builder(T subject) {
-      this.subject = subject;
-    }
-
-    @CheckReturnValue
-    T getSubject() {
-      return subject;
-    }
-
-    Builder<T> addItems(Iterable<Item> newItems) {
-      items.addAll(newItems);
-      return this;
-    }
-
-    Builder<T> addError(String message) {
-      return addError(message, subject);
-    }
-
-    Builder<T> addError(String message, Element element) {
-      return addItem(message, ERROR, element);
-    }
-
-    Builder<T> addError(String message, Element element, AnnotationMirror annotation) {
-      return addItem(message, ERROR, element, annotation);
-    }
-
-    Builder<T> addError(
-        String message,
-        Element element,
-        AnnotationMirror annotation,
-        AnnotationValue annotationValue) {
-      return addItem(message, ERROR, element, annotation, annotationValue);
-    }
-
-    Builder<T> addWarning(String message) {
-      return addWarning(message, subject);
-    }
-
-    Builder<T> addWarning(String message, Element element) {
-      return addItem(message, WARNING, element);
-    }
-
-    Builder<T> addWarning(String message, Element element, AnnotationMirror annotation) {
-      return addItem(message, WARNING, element, annotation);
-    }
-
-    Builder<T> addWarning(
-        String message,
-        Element element,
-        AnnotationMirror annotation,
-        AnnotationValue annotationValue) {
-      return addItem(message, WARNING, element, annotation, annotationValue);
-    }
-
-    Builder<T> addNote(String message) {
-      return addNote(message, subject);
-    }
-
-    Builder<T> addNote(String message, Element element) {
-      return addItem(message, NOTE, element);
-    }
-
-    Builder<T> addNote(String message, Element element, AnnotationMirror annotation) {
-      return addItem(message, NOTE, element, annotation);
-    }
-
-    Builder<T> addNote(
-        String message,
-        Element element,
-        AnnotationMirror annotation,
-        AnnotationValue annotationValue) {
-      return addItem(message, NOTE, element, annotation, annotationValue);
-    }
-
-    Builder<T> addItem(String message, Kind kind, Element element) {
-      return addItem(message, kind, element, Optional.empty(), Optional.empty());
-    }
-
-    Builder<T> addItem(String message, Kind kind, Element element, AnnotationMirror annotation) {
-      return addItem(message, kind, element, Optional.of(annotation), Optional.empty());
-    }
-
-    Builder<T> addItem(
-        String message,
-        Kind kind,
-        Element element,
-        AnnotationMirror annotation,
-        AnnotationValue annotationValue) {
-      return addItem(message, kind, element, Optional.of(annotation), Optional.of(annotationValue));
-    }
-
-    private Builder<T> addItem(
-        String message,
-        Kind kind,
-        Element element,
-        Optional<AnnotationMirror> annotation,
-        Optional<AnnotationValue> annotationValue) {
-      items.add(
-          new AutoValue_ValidationReport_Item(message, kind, element, annotation, annotationValue));
-      return this;
-    }
-
-    /**
-     * If called, then {@link #isClean()} will return {@code false} even if there are no error items
-     * in the report.
-     */
-    void markDirty() {
-      this.markedDirty = true;
-    }
-
-    Builder<T> addSubreport(ValidationReport<?> subreport) {
-      subreports.add(subreport);
-      return this;
-    }
-
-    @CheckReturnValue
-    ValidationReport<T> build() {
-      return new AutoValue_ValidationReport<>(
-          subject, items.build(), subreports.build(), markedDirty);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/ValidationType.java b/java/dagger/internal/codegen/ValidationType.java
deleted file mode 100644
index 5d19dc1..0000000
--- a/java/dagger/internal/codegen/ValidationType.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 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 java.util.Optional;
-import javax.tools.Diagnostic;
-
-/**
- * Allows options to control how component process validates things such as scope cycles
- * or nullability.
- */
-enum ValidationType {
-  ERROR,
-  WARNING,
-  NONE;
-
-  Optional<Diagnostic.Kind> diagnosticKind() {
-    switch (this) {
-      case ERROR:
-        return Optional.of(Diagnostic.Kind.ERROR);
-      case WARNING:
-        return Optional.of(Diagnostic.Kind.WARNING);
-      default:
-        return Optional.empty();
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/bootstrap_compiler_deploy.jar b/java/dagger/internal/codegen/bootstrap_compiler_deploy.jar
deleted file mode 100644
index ad9761d..0000000
--- a/java/dagger/internal/codegen/bootstrap_compiler_deploy.jar
+++ /dev/null
Binary files differ
diff --git a/java/dagger/internal/codegen/dagger_statistics.proto b/java/dagger/internal/codegen/dagger_statistics.proto
deleted file mode 100644
index 273e472..0000000
--- a/java/dagger/internal/codegen/dagger_statistics.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-syntax = "proto2";
-
-package dagger.internal.codegen.proto;
-option java_package = "dagger.internal.codegen.proto";
-
-import "google/protobuf/duration.proto";
-
-message DaggerBuildStatistics {
-  optional google.protobuf.Duration total_processing_time = 1;
-  repeated DaggerRound rounds = 2;
-}
-
-// Duration of each Dagger ProcessingStep for a single annotation processing
-// round.
-message DaggerRound {
-  optional google.protobuf.Duration map_key_step_time = 1;
-  optional google.protobuf.Duration inject_step_time = 2;
-  optional google.protobuf.Duration monitoring_module_step_time = 3;
-  optional google.protobuf.Duration multibinding_annotations_step_time = 4;
-  optional google.protobuf.Duration binds_instance_step_time = 5;
-  optional google.protobuf.Duration module_step_time = 6;
-  optional google.protobuf.Duration component_step_time = 7;
-  optional google.protobuf.Duration component_hjar_step_time = 8;
-  optional google.protobuf.Duration binding_method_step_time = 9;
-}
diff --git a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java b/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java
deleted file mode 100644
index cc0d7de..0000000
--- a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 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.javapoet;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Ascii;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.squareup.javapoet.AnnotationSpec;
-import java.util.Arrays;
-
-/** Static factories to create {@link AnnotationSpec}s. */
-public final class AnnotationSpecs {
-  /** Values for an {@link SuppressWarnings} annotation. */
-  public enum Suppression {
-    RAWTYPES,
-    UNCHECKED,
-    ;
-
-    @Override
-    public String toString() {
-      return Ascii.toLowerCase(name());
-    }
-  }
-
-  /** Creates an {@link AnnotationSpec} for {@link SuppressWarnings}. */
-  public static AnnotationSpec suppressWarnings(Suppression first, Suppression... rest) {
-    checkNotNull(first);
-    Arrays.stream(rest).forEach(Preconditions::checkNotNull);
-    AnnotationSpec.Builder builder = AnnotationSpec.builder(SuppressWarnings.class);
-    Lists.asList(first, rest).forEach(suppression -> builder.addMember("value", "$S", suppression));
-    return builder.build();
-  }
-
-  private AnnotationSpecs() {}
-}
diff --git a/java/dagger/internal/codegen/javapoet/BUILD b/java/dagger/internal/codegen/javapoet/BUILD
deleted file mode 100644
index f829d49..0000000
--- a/java/dagger/internal/codegen/javapoet/BUILD
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   JavaPoet extensions for use in Dagger
-
-package(default_visibility = ["//:src"])
-
-java_library(
-    name = "javapoet",
-    srcs = glob(["*.java"]),
-    plugins = ["//java/dagger/internal/codegen:bootstrap_compiler_plugin"],
-    tags = ["maven:merged"],
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/producers",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-    ],
-)
diff --git a/java/dagger/internal/codegen/javapoet/CodeBlocks.java b/java/dagger/internal/codegen/javapoet/CodeBlocks.java
deleted file mode 100644
index 3e9f75d..0000000
--- a/java/dagger/internal/codegen/javapoet/CodeBlocks.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2016 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.javapoet;
-
-import static com.squareup.javapoet.MethodSpec.methodBuilder;
-import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName;
-import static java.util.stream.StreamSupport.stream;
-import static javax.lang.model.element.Modifier.PUBLIC;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeName;
-import java.util.stream.Collector;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-
-/** Convenience methods for creating {@link CodeBlock}s. */
-public final class CodeBlocks {
-  /**
-   * Joins {@link CodeBlock} instances in a manner suitable for use as method parameters (or
-   * arguments).
-   */
-  public static Collector<CodeBlock, ?, CodeBlock> toParametersCodeBlock() {
-    // TODO(ronshapiro,jakew): consider adding zero-width spaces to help line breaking when the
-    // formatter is off. If not, inline this
-    return CodeBlock.joining(", ");
-  }
-
-  /** Concatenates {@link CodeBlock} instances separated by newlines for readability. */
-  public static Collector<CodeBlock, ?, CodeBlock> toConcatenatedCodeBlock() {
-    return CodeBlock.joining("\n", "", "\n");
-  }
-
-  /** Returns a comma-separated version of {@code codeBlocks} as one unified {@link CodeBlock}. */
-  public static CodeBlock makeParametersCodeBlock(Iterable<CodeBlock> codeBlocks) {
-    return stream(codeBlocks.spliterator(), false).collect(toParametersCodeBlock());
-  }
-
-  /**
-   * Returns a comma-separated {@link CodeBlock} using the name of every parameter in {@code
-   * parameters}.
-   */
-  public static CodeBlock parameterNames(Iterable<ParameterSpec> parameters) {
-    // TODO(ronshapiro): Add DaggerStreams.stream(Iterable)
-    return stream(parameters.spliterator(), false)
-        .map(p -> CodeBlock.of("$N", p))
-        .collect(toParametersCodeBlock());
-  }
-
-  /**
-   * Returns one unified {@link CodeBlock} which joins each item in {@code codeBlocks} with a
-   * newline.
-   */
-  public static CodeBlock concat(Iterable<CodeBlock> codeBlocks) {
-    return stream(codeBlocks.spliterator(), false).collect(toConcatenatedCodeBlock());
-  }
-
-  /** Adds an annotation to a method. */
-  public static void addAnnotation(MethodSpec.Builder method, DeclaredType nullableType) {
-    method.addAnnotation(ClassName.get(MoreTypes.asTypeElement(nullableType)));
-  }
-
-  /**
-   * Returns an anonymous {@link javax.inject.Provider} class with the single {@link
-   * javax.inject.Provider#get()} method that returns the given {@code expression}.
-   */
-  public static CodeBlock anonymousProvider(Expression expression) {
-    // More of a precondition check that the type Provider is parameterized with is a DeclaredType
-    DeclaredType type = MoreTypes.asDeclared(expression.type());
-    return anonymousProvider(
-        TypeName.get(type), CodeBlock.of("return $L;", expression.codeBlock()));
-  }
-
-  /**
-   * Returns an anonymous {@link javax.inject.Provider} class with the single {@link
-   * javax.inject.Provider#get()} method implemented by {@code body}.
-   */
-  public static CodeBlock anonymousProvider(TypeName providedType, CodeBlock body) {
-    return CodeBlock.of(
-        "$L",
-        anonymousClassBuilder("")
-            .superclass(providerOf(providedType))
-            .addMethod(
-                methodBuilder("get")
-                    .addAnnotation(Override.class)
-                    .addModifiers(PUBLIC)
-                    .returns(providedType)
-                    .addCode(body)
-                    .build())
-            .build());
-  }
-
-  /** Returns {@code expression} cast to a type. */
-  public static CodeBlock cast(CodeBlock expression, Class<?> castTo) {
-    return CodeBlock.of("($T) $L", castTo, expression);
-  }
-
-  public static CodeBlock type(TypeMirror type) {
-    return CodeBlock.of("$T", type);
-  }
-
-  public static CodeBlock stringLiteral(String toWrap) {
-    return CodeBlock.of("$S", toWrap);
-  }
-
-  /** Returns a javadoc {@literal @link} tag that poins to the given {@link ExecutableElement}. */
-  public static CodeBlock javadocLinkTo(ExecutableElement executableElement) {
-    CodeBlock.Builder builder =
-        CodeBlock.builder()
-            .add(
-                "{@link $T#",
-                rawTypeName(
-                    ClassName.get(MoreElements.asType(executableElement.getEnclosingElement()))));
-    switch (executableElement.getKind()) {
-      case METHOD:
-        builder.add("$L", executableElement.getSimpleName());
-        break;
-      case CONSTRUCTOR:
-        builder.add("$L", executableElement.getEnclosingElement().getSimpleName());
-        break;
-      case STATIC_INIT:
-      case INSTANCE_INIT:
-        throw new IllegalArgumentException(
-            "cannot create a javadoc link to an initializer: " + executableElement);
-      default:
-        throw new AssertionError(executableElement.toString());
-    }
-    builder.add("(");
-    builder.add(
-        executableElement.getParameters().stream()
-            .map(parameter -> CodeBlock.of("$T", rawTypeName(TypeName.get(parameter.asType()))))
-            .collect(toParametersCodeBlock()));
-    return builder.add(")}").build();
-  }
-
-  private CodeBlocks() {}
-}
diff --git a/java/dagger/internal/codegen/javapoet/Expression.java b/java/dagger/internal/codegen/javapoet/Expression.java
deleted file mode 100644
index b79c55c..0000000
--- a/java/dagger/internal/codegen/javapoet/Expression.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 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.javapoet;
-
-import com.google.auto.common.MoreTypes;
-import com.squareup.javapoet.CodeBlock;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Encapsulates a {@link CodeBlock} for an <a
- * href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html">expression</a> and the
- * {@link TypeMirror} that it represents from the perspective of the compiler. Consider the
- * following example:
- *
- * <pre><code>
- *   {@literal @SuppressWarnings("rawtypes")}
- *   private Provider fooImplProvider = DoubleCheck.provider(FooImpl_Factory.create());
- * </code></pre>
- *
- * <p>An {@code Expression} for {@code fooImplProvider.get()} would have a {@link #type()} of {@code
- * java.lang.Object} and not {@code FooImpl}.
- */
-public final class Expression {
-  private final TypeMirror type;
-  private final CodeBlock codeBlock;
-
-  private Expression(TypeMirror type, CodeBlock codeBlock) {
-    this.type = type;
-    this.codeBlock = codeBlock;
-  }
-
-  /** Creates a new {@link Expression} with a {@link TypeMirror} and {@link CodeBlock}. */
-  public static Expression create(TypeMirror type, CodeBlock expression) {
-    return new Expression(type, expression);
-  }
-
-  /**
-   * Creates a new {@link Expression} with a {@link TypeMirror}, {@linkplain CodeBlock#of(String,
-   * Object[]) format, and arguments}.
-   */
-  public static Expression create(TypeMirror type, String format, Object... args) {
-    return create(type, CodeBlock.of(format, args));
-  }
-
-  /** Returns a new expression that casts the current expression to {@code newType}. */
-  // TODO(ronshapiro): consider overloads that take a Types and Elements and only cast if necessary,
-  // or just embedding a Types/Elements instance in an Expression.
-  public Expression castTo(TypeMirror newType) {
-    return create(newType, "($T) $L", newType, codeBlock);
-  }
-
-  /**
-   * Returns a new expression that {@link #castTo(TypeMirror)} casts the current expression to its
-   * boxed type if this expression has a primitive type.
-   */
-  public Expression box(DaggerTypes types) {
-    return type.getKind().isPrimitive()
-        ? castTo(types.boxedClass(MoreTypes.asPrimitiveType(type)).asType())
-        : this;
-  }
-
-  /** The {@link TypeMirror type} to which the expression evaluates. */
-  public TypeMirror type() {
-    return type;
-  }
-
-  /** The code of the expression. */
-  public CodeBlock codeBlock() {
-    return codeBlock;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("[%s] %s", type, codeBlock);
-  }
-}
diff --git a/java/dagger/internal/codegen/javapoet/TypeNames.java b/java/dagger/internal/codegen/javapoet/TypeNames.java
deleted file mode 100644
index 9301dbc..0000000
--- a/java/dagger/internal/codegen/javapoet/TypeNames.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2016 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.javapoet;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import dagger.Lazy;
-import dagger.MembersInjector;
-import dagger.internal.DoubleCheck;
-import dagger.internal.Factory;
-import dagger.internal.InstanceFactory;
-import dagger.internal.MapFactory;
-import dagger.internal.MapProviderFactory;
-import dagger.internal.MembersInjectors;
-import dagger.internal.ProviderOfLazy;
-import dagger.internal.SetFactory;
-import dagger.internal.SingleCheck;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.internal.AbstractProducer;
-import dagger.producers.internal.DependencyMethodProducer;
-import dagger.producers.internal.MapOfProducedProducer;
-import dagger.producers.internal.MapOfProducerProducer;
-import dagger.producers.internal.MapProducer;
-import dagger.producers.internal.Producers;
-import dagger.producers.internal.SetOfProducedProducer;
-import dagger.producers.internal.SetProducer;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.List;
-import java.util.Set;
-import javax.inject.Provider;
-
-/** Common names and convenience methods for JavaPoet {@link TypeName} usage. */
-public final class TypeNames {
-
-  public static final ClassName ABSTRACT_PRODUCER = ClassName.get(AbstractProducer.class);
-  public static final ClassName DEPENDENCY_METHOD_PRODUCER =
-      ClassName.get(DependencyMethodProducer.class);
-  public static final ClassName DOUBLE_CHECK = ClassName.get(DoubleCheck.class);
-  public static final ClassName FACTORY = ClassName.get(Factory.class);
-  public static final ClassName FUTURES = ClassName.get(Futures.class);
-  public static final ClassName INSTANCE_FACTORY = ClassName.get(InstanceFactory.class);
-  public static final ClassName LAZY = ClassName.get(Lazy.class);
-  public static final ClassName LIST = ClassName.get(List.class);
-  public static final ClassName LISTENABLE_FUTURE = ClassName.get(ListenableFuture.class);
-  public static final ClassName MAP_FACTORY = ClassName.get(MapFactory.class);
-  public static final ClassName MAP_OF_PRODUCED_PRODUCER =
-      ClassName.get(MapOfProducedProducer.class);
-  public static final ClassName MAP_OF_PRODUCER_PRODUCER =
-      ClassName.get(MapOfProducerProducer.class);
-  public static final ClassName MAP_PRODUCER = ClassName.get(MapProducer.class);
-  public static final ClassName MAP_PROVIDER_FACTORY = ClassName.get(MapProviderFactory.class);
-  public static final ClassName MEMBERS_INJECTOR = ClassName.get(MembersInjector.class);
-  public static final ClassName MEMBERS_INJECTORS = ClassName.get(MembersInjectors.class);
-  public static final ClassName PRODUCER_TOKEN = ClassName.get(ProducerToken.class);
-  public static final ClassName PRODUCED = ClassName.get(Produced.class);
-  public static final ClassName PRODUCER = ClassName.get(Producer.class);
-  public static final ClassName PRODUCERS = ClassName.get(Producers.class);
-  public static final ClassName PRODUCTION_COMPONENT_MONITOR_FACTORY =
-      ClassName.get(ProductionComponentMonitor.Factory.class);
-  public static final ClassName PROVIDER = ClassName.get(Provider.class);
-  public static final ClassName PROVIDER_OF_LAZY = ClassName.get(ProviderOfLazy.class);
-  public static final ClassName SET = ClassName.get(Set.class);
-  public static final ClassName SET_FACTORY = ClassName.get(SetFactory.class);
-  public static final ClassName SET_OF_PRODUCED_PRODUCER =
-      ClassName.get(SetOfProducedProducer.class);
-  public static final ClassName SET_PRODUCER = ClassName.get(SetProducer.class);
-  public static final ClassName SINGLE_CHECK = ClassName.get(SingleCheck.class);
-
-  /**
-   * {@link TypeName#VOID} is lowercase-v {@code void} whereas this represents the class, {@link
-   * Void}.
-   */
-  public static final ClassName VOID_CLASS = ClassName.get(Void.class);
-
-  public static ParameterizedTypeName abstractProducerOf(TypeName typeName) {
-    return ParameterizedTypeName.get(ABSTRACT_PRODUCER, typeName);
-  }
-
-  public static ParameterizedTypeName factoryOf(TypeName factoryType) {
-    return ParameterizedTypeName.get(FACTORY, factoryType);
-  }
-
-  public static ParameterizedTypeName lazyOf(TypeName typeName) {
-    return ParameterizedTypeName.get(LAZY, typeName);
-  }
-
-  public static ParameterizedTypeName listOf(TypeName typeName) {
-    return ParameterizedTypeName.get(LIST, typeName);
-  }
-
-  public static ParameterizedTypeName listenableFutureOf(TypeName typeName) {
-    return ParameterizedTypeName.get(LISTENABLE_FUTURE, typeName);
-  }
-
-  public static ParameterizedTypeName membersInjectorOf(TypeName membersInjectorType) {
-    return ParameterizedTypeName.get(MEMBERS_INJECTOR, membersInjectorType);
-  }
-
-  public static ParameterizedTypeName producedOf(TypeName typeName) {
-    return ParameterizedTypeName.get(PRODUCED, typeName);
-  }
-
-  public static ParameterizedTypeName producerOf(TypeName typeName) {
-    return ParameterizedTypeName.get(PRODUCER, typeName);
-  }
-
-  public static ParameterizedTypeName dependencyMethodProducerOf(TypeName typeName) {
-    return ParameterizedTypeName.get(DEPENDENCY_METHOD_PRODUCER, typeName);
-  }
-
-  public static ParameterizedTypeName providerOf(TypeName typeName) {
-    return ParameterizedTypeName.get(PROVIDER, typeName);
-  }
-
-  public static ParameterizedTypeName setOf(TypeName elementType) {
-    return ParameterizedTypeName.get(SET, elementType);
-  }
-
-  /**
-   * Returns the {@link TypeName} for the raw type of the given type name. If the argument isn't a
-   * parameterized type, it returns the argument unchanged.
-   */
-  public static TypeName rawTypeName(TypeName typeName) {
-    return (typeName instanceof ParameterizedTypeName)
-        ? ((ParameterizedTypeName) typeName).rawType
-        : typeName;
-  }
-
-  private TypeNames() {}
-}
diff --git a/java/dagger/internal/codegen/javapoet/TypeSpecs.java b/java/dagger/internal/codegen/javapoet/TypeSpecs.java
deleted file mode 100644
index 8ec8747..0000000
--- a/java/dagger/internal/codegen/javapoet/TypeSpecs.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 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.javapoet;
-
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeSpec;
-import javax.lang.model.element.TypeElement;
-
-/** Convenience methods for use with JavaPoet's {@link TypeSpec}. */
-public final class TypeSpecs {
-
-  /**
-   * If {@code supertype} is a class, adds it as a superclass for {@code typeBuilder}; if it is an
-   * interface, adds it as a superinterface.
-   *
-   * @return {@code typeBuilder}
-   */
-  @CanIgnoreReturnValue
-  public static TypeSpec.Builder addSupertype(TypeSpec.Builder typeBuilder, TypeElement supertype) {
-    switch (supertype.getKind()) {
-      case CLASS:
-        return typeBuilder.superclass(ClassName.get(supertype));
-      case INTERFACE:
-        return typeBuilder.addSuperinterface(ClassName.get(supertype));
-      default:
-        throw new AssertionError(supertype + " is neither a class nor an interface.");
-    }
-  }
-
-  private TypeSpecs() {}
-}
diff --git a/java/dagger/internal/codegen/kythe_plugin_deploy.jar b/java/dagger/internal/codegen/kythe_plugin_deploy.jar
deleted file mode 100644
index 3a1eed2..0000000
--- a/java/dagger/internal/codegen/kythe_plugin_deploy.jar
+++ /dev/null
Binary files differ
diff --git a/java/dagger/internal/codegen/langmodel/Accessibility.java b/java/dagger/internal/codegen/langmodel/Accessibility.java
deleted file mode 100644
index 62c1fbd..0000000
--- a/java/dagger/internal/codegen/langmodel/Accessibility.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2015 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.langmodel;
-
-import static com.google.auto.common.MoreElements.getPackage;
-import static com.google.common.base.Preconditions.checkArgument;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.lang.model.element.Modifier.PUBLIC;
-
-import com.google.auto.common.MoreElements;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.SimpleElementVisitor6;
-import javax.lang.model.util.SimpleTypeVisitor6;
-import javax.lang.model.util.SimpleTypeVisitor8;
-
-/**
- * Utility methods for determining whether a {@linkplain TypeMirror type} or an {@linkplain Element
- * element} is accessible given the rules outlined in <a
- * href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6">section 6.6 of the
- * Java Language Specification</a>.
- *
- * <p>This class only provides an approximation for accessibility. It does not always yield the same
- * result as the compiler, but will always err on the side of declaring something inaccessible. This
- * ensures that using this class will never result in generating code that will not compile.
- *
- * <p>Whenever compiler independence is not a requirement, the compiler-specific implementation of
- * this functionality should be preferred. For example, {@link
- * com.sun.source.util.Trees#isAccessible(com.sun.source.tree.Scope, TypeElement)} would be
- * preferable for {@code javac}.
- */
-public final class Accessibility {
-  /** Returns true if the given type can be referenced from any package. */
-  public static boolean isTypePubliclyAccessible(TypeMirror type) {
-    return type.accept(new TypeAccessibilityVisitor(), null);
-  }
-
-  /** Returns true if the given type can be referenced from code in the given package. */
-  public static boolean isTypeAccessibleFrom(TypeMirror type, String packageName) {
-    return type.accept(new TypeAccessibilityVisitor(packageName), null);
-  }
-
-  private static boolean isTypeAccessibleFrom(TypeMirror type, Optional<String> packageName) {
-    return type.accept(new TypeAccessibilityVisitor(packageName), null);
-  }
-
-  private static final class TypeAccessibilityVisitor extends SimpleTypeVisitor6<Boolean, Void> {
-    final Optional<String> packageName;
-
-    TypeAccessibilityVisitor() {
-      this(Optional.empty());
-    }
-
-    TypeAccessibilityVisitor(String packageName) {
-      this(Optional.of(packageName));
-    }
-
-    TypeAccessibilityVisitor(Optional<String> packageName) {
-      this.packageName = packageName;
-    }
-
-    boolean isAccessible(TypeMirror type) {
-      return type.accept(this, null);
-    }
-
-    @Override
-    public Boolean visitNoType(NoType type, Void p) {
-      return true;
-    }
-
-    @Override
-    public Boolean visitDeclared(DeclaredType type, Void p) {
-      if (!isAccessible(type.getEnclosingType())) {
-        // TODO(gak): investigate this check.  see comment in Binding
-        return false;
-      }
-      if (!isElementAccessibleFrom(type.asElement(), packageName)) {
-        return false;
-      }
-      for (TypeMirror typeArgument : type.getTypeArguments()) {
-        if (!isAccessible(typeArgument)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    public Boolean visitArray(ArrayType type, Void p) {
-      return type.getComponentType().accept(this, null);
-    }
-
-    @Override
-    public Boolean visitPrimitive(PrimitiveType type, Void p) {
-      return true;
-    }
-
-    @Override
-    public Boolean visitNull(NullType type, Void p) {
-      return true;
-    }
-
-    @Override
-    public Boolean visitTypeVariable(TypeVariable type, Void p) {
-      // a _reference_ to a type variable is always accessible
-      return true;
-    }
-
-    @Override
-    public Boolean visitWildcard(WildcardType type, Void p) {
-      if (type.getExtendsBound() != null && !isAccessible(type.getExtendsBound())) {
-        return false;
-      }
-      if (type.getSuperBound() != null && !isAccessible(type.getSuperBound())) {
-        return false;
-      }
-      return true;
-    }
-
-    @Override
-    protected Boolean defaultAction(TypeMirror type, Void p) {
-      throw new IllegalArgumentException(
-          String.format(
-              "%s of kind %s should not be checked for accessibility", type, type.getKind()));
-    }
-  }
-
-  /** Returns true if the given element can be referenced from any package. */
-  public static boolean isElementPubliclyAccessible(Element element) {
-    return element.accept(new ElementAccessibilityVisitor(), null);
-  }
-
-  /** Returns true if the given element can be referenced from code in the given package. */
-  // TODO(gak): account for protected
-  public static boolean isElementAccessibleFrom(Element element, String packageName) {
-    return element.accept(new ElementAccessibilityVisitor(packageName), null);
-  }
-
-  private static boolean isElementAccessibleFrom(Element element, Optional<String> packageName) {
-    return element.accept(new ElementAccessibilityVisitor(packageName), null);
-  }
-
-  /** Returns true if the given element can be referenced from other code in its own package. */
-  public static boolean isElementAccessibleFromOwnPackage(Element element) {
-    return isElementAccessibleFrom(
-        element, MoreElements.getPackage(element).getQualifiedName().toString());
-  }
-
-  private static final class ElementAccessibilityVisitor
-      extends SimpleElementVisitor6<Boolean, Void> {
-    final Optional<String> packageName;
-
-    ElementAccessibilityVisitor() {
-      this(Optional.empty());
-    }
-
-    ElementAccessibilityVisitor(String packageName) {
-      this(Optional.of(packageName));
-    }
-
-    ElementAccessibilityVisitor(Optional<String> packageName) {
-      this.packageName = packageName;
-    }
-
-    @Override
-    public Boolean visitPackage(PackageElement element, Void p) {
-      return true;
-    }
-
-    @Override
-    public Boolean visitType(TypeElement element, Void p) {
-      switch (element.getNestingKind()) {
-        case MEMBER:
-          return accessibleMember(element);
-        case TOP_LEVEL:
-          return accessibleModifiers(element);
-        case ANONYMOUS:
-        case LOCAL:
-          return false;
-      }
-      throw new AssertionError();
-    }
-
-    boolean accessibleMember(Element element) {
-      if (!element.getEnclosingElement().accept(this, null)) {
-        return false;
-      }
-      return accessibleModifiers(element);
-    }
-
-    boolean accessibleModifiers(Element element) {
-      if (element.getModifiers().contains(PUBLIC)) {
-        return true;
-      } else if (element.getModifiers().contains(PRIVATE)) {
-        return false;
-      } else if (packageName.isPresent()
-          && getPackage(element).getQualifiedName().contentEquals(packageName.get())) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public Boolean visitTypeParameter(TypeParameterElement element, Void p) {
-      throw new IllegalArgumentException(
-          "It does not make sense to check the accessibility of a type parameter");
-    }
-
-    @Override
-    public Boolean visitExecutable(ExecutableElement element, Void p) {
-      return accessibleMember(element);
-    }
-
-    @Override
-    public Boolean visitVariable(VariableElement element, Void p) {
-      ElementKind kind = element.getKind();
-      checkArgument(kind.isField(), "checking a variable that isn't a field: %s", kind);
-      return accessibleMember(element);
-    }
-  }
-
-  private static final TypeVisitor<Boolean, Optional<String>> RAW_TYPE_ACCESSIBILITY_VISITOR =
-      new SimpleTypeVisitor8<Boolean, Optional<String>>() {
-        @Override
-        protected Boolean defaultAction(TypeMirror e, Optional<String> requestingPackage) {
-          return isTypeAccessibleFrom(e, requestingPackage);
-        }
-
-        @Override
-        public Boolean visitDeclared(DeclaredType t, Optional<String> requestingPackage) {
-          return isElementAccessibleFrom(t.asElement(), requestingPackage);
-        }
-      };
-
-  /** Returns true if the raw type of {@code type} is accessible from the given package. */
-  public static boolean isRawTypeAccessible(TypeMirror type, String requestingPackage) {
-    return type.accept(RAW_TYPE_ACCESSIBILITY_VISITOR, Optional.of(requestingPackage));
-  }
-
-  /** Returns true if the raw type of {@code type} is accessible from any package. */
-  public static boolean isRawTypePubliclyAccessible(TypeMirror type) {
-    return type.accept(RAW_TYPE_ACCESSIBILITY_VISITOR, Optional.empty());
-  }
-
-  private Accessibility() {}
-}
diff --git a/java/dagger/internal/codegen/langmodel/BUILD b/java/dagger/internal/codegen/langmodel/BUILD
deleted file mode 100644
index 16fa5d8..0000000
--- a/java/dagger/internal/codegen/langmodel/BUILD
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Dagger-specific extensions to the javax.lang.model APIs
-
-package(default_visibility = ["//:src"])
-
-java_library(
-    name = "langmodel",
-    srcs = glob(["*.java"]),
-    plugins = ["//java/dagger/internal/codegen:bootstrap_compiler_plugin"],
-    tags = ["maven:merged"],
-    deps = [
-        "//java/dagger:core",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-    ],
-)
diff --git a/java/dagger/internal/codegen/langmodel/DaggerElements.java b/java/dagger/internal/codegen/langmodel/DaggerElements.java
deleted file mode 100644
index 873ad3d..0000000
--- a/java/dagger/internal/codegen/langmodel/DaggerElements.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2013 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.langmodel;
-
-import static com.google.auto.common.MoreElements.asExecutable;
-import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
-import static com.google.auto.common.MoreElements.hasModifiers;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.asList;
-import static java.util.Comparator.comparing;
-import static java.util.stream.Collectors.toSet;
-import static javax.lang.model.element.Modifier.ABSTRACT;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.graph.Traverser;
-import com.squareup.javapoet.ClassName;
-import dagger.Reusable;
-import java.io.Writer;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Predicate;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleElementVisitor8;
-import javax.lang.model.util.Types;
-
-/** Extension of {@link Elements} that adds Dagger-specific methods. */
-@Reusable
-public final class DaggerElements implements Elements {
-
-  private final Elements elements;
-  private final Types types;
-
-  public DaggerElements(Elements elements, Types types) {
-    this.elements = checkNotNull(elements);
-    this.types = checkNotNull(types);
-  }
-
-  public DaggerElements(ProcessingEnvironment processingEnv) {
-    this(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
-  }
-
-  /**
-   * Returns {@code true} if {@code encloser} is equal to {@code enclosed} or recursively encloses
-   * it.
-   */
-  public static boolean elementEncloses(TypeElement encloser, Element enclosed) {
-    return Iterables.contains(GET_ENCLOSED_ELEMENTS.breadthFirst(encloser), enclosed);
-  }
-
-  private static final Traverser<Element> GET_ENCLOSED_ELEMENTS =
-      Traverser.forTree(Element::getEnclosedElements);
-
-  public ImmutableSet<ExecutableElement> getUnimplementedMethods(TypeElement type) {
-    return FluentIterable.from(getLocalAndInheritedMethods(type, types, elements))
-        .filter(hasModifiers(ABSTRACT))
-        .toSet();
-  }
-
-  /** Returns the type element for a class. */
-  public TypeElement getTypeElement(Class<?> clazz) {
-    return getTypeElement(clazz.getCanonicalName());
-  }
-
-  @Override
-  public TypeElement getTypeElement(CharSequence name) {
-    return elements.getTypeElement(name);
-  }
-
-  /** Returns the type element for a class name. */
-  public TypeElement getTypeElement(ClassName className) {
-    return getTypeElement(className.withoutAnnotations().toString());
-  }
-
-  /** Returns the argument or the closest enclosing element that is a {@link TypeElement}. */
-  public static TypeElement closestEnclosingTypeElement(Element element) {
-    return element.accept(CLOSEST_ENCLOSING_TYPE_ELEMENT, null);
-  }
-
-  private static final ElementVisitor<TypeElement, Void> CLOSEST_ENCLOSING_TYPE_ELEMENT =
-      new SimpleElementVisitor8<TypeElement, Void>() {
-        @Override
-        protected TypeElement defaultAction(Element element, Void p) {
-          return element.getEnclosingElement().accept(this, null);
-        }
-
-        @Override
-        public TypeElement visitType(TypeElement type, Void p) {
-          return type;
-        }
-      };
-
-  /**
-   * Compares elements according to their declaration order among siblings. Only valid to compare
-   * elements enclosed by the same parent.
-   */
-  public static final Comparator<Element> DECLARATION_ORDER =
-      comparing(element -> siblings(element).indexOf(element));
-
-  // For parameter elements, element.getEnclosingElement().getEnclosedElements() is empty. So
-  // instead look at the parameter list of the enclosing executable.
-  private static List<? extends Element> siblings(Element element) {
-    return element.getKind().equals(ElementKind.PARAMETER)
-        ? asExecutable(element.getEnclosingElement()).getParameters()
-        : element.getEnclosingElement().getEnclosedElements();
-  }
-
-  /**
-   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain
-   * AnnotationMirror#getAnnotationType() annotation type} has the same canonical name as any of
-   * that of {@code annotationClasses}.
-   */
-  public static boolean isAnyAnnotationPresent(
-      Element element, Iterable<? extends Class<? extends Annotation>> annotationClasses) {
-    for (Class<? extends Annotation> annotation : annotationClasses) {
-      if (MoreElements.isAnnotationPresent(element, annotation)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @SafeVarargs
-  public static boolean isAnyAnnotationPresent(
-      Element element,
-      Class<? extends Annotation> first,
-      Class<? extends Annotation>... otherAnnotations) {
-    return isAnyAnnotationPresent(element, asList(first, otherAnnotations));
-  }
-
-  /**
-   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain
-   * AnnotationMirror#getAnnotationType() annotation type} is equivalent to {@code annotationType}.
-   */
-  public static boolean isAnnotationPresent(Element element, TypeMirror annotationType) {
-    return element.getAnnotationMirrors().stream()
-        .map(AnnotationMirror::getAnnotationType)
-        .anyMatch(candidate -> MoreTypes.equivalence().equivalent(candidate, annotationType));
-  }
-
-  /**
-   * Returns the annotation present on {@code element} whose type is {@code first} or within {@code
-   * rest}, checking each annotation type in order.
-   */
-  @SafeVarargs
-  public static Optional<AnnotationMirror> getAnyAnnotation(
-      Element element, Class<? extends Annotation> first, Class<? extends Annotation>... rest) {
-    return getAnyAnnotation(element, asList(first, rest));
-  }
-
-  /**
-   * Returns the annotation present on {@code element} whose type is in {@code annotations},
-   * checking each annotation type in order.
-   */
-  public static Optional<AnnotationMirror> getAnyAnnotation(
-      Element element, Collection<? extends Class<? extends Annotation>> annotations) {
-    return element.getAnnotationMirrors().stream()
-        .filter(hasAnnotationTypeIn(annotations))
-        .map((AnnotationMirror a) -> a) // Avoid returning Optional<? extends AnnotationMirror>.
-        .findFirst();
-  }
-
-  /** Returns the annotations present on {@code element} of all types. */
-  @SafeVarargs
-  public static ImmutableSet<AnnotationMirror> getAllAnnotations(
-      Element element, Class<? extends Annotation> first, Class<? extends Annotation>... rest) {
-    return ImmutableSet.copyOf(
-        Iterables.filter(
-            element.getAnnotationMirrors(), hasAnnotationTypeIn(asList(first, rest))::test));
-  }
-
-  /**
-   * Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClass} on
-   * {@code element}, or {@link Optional#empty()} if no such annotation exists. This method is a
-   * safer alternative to calling {@link Element#getAnnotation} as it avoids any interaction with
-   * annotation proxies.
-   */
-  public static Optional<AnnotationMirror> getAnnotationMirror(
-      Element element, Class<? extends Annotation> annotationClass) {
-    return Optional.ofNullable(MoreElements.getAnnotationMirror(element, annotationClass).orNull());
-  }
-
-  private static Predicate<AnnotationMirror> hasAnnotationTypeIn(
-      Collection<? extends Class<? extends Annotation>> annotations) {
-    Set<String> annotationClassNames =
-        annotations.stream().map(Class::getCanonicalName).collect(toSet());
-    return annotation ->
-        annotationClassNames.contains(
-            MoreTypes.asTypeElement(annotation.getAnnotationType()).getQualifiedName().toString());
-  }
-
-  public static ImmutableSet<String> suppressedWarnings(Element element) {
-    SuppressWarnings suppressedWarnings = element.getAnnotation(SuppressWarnings.class);
-    if (suppressedWarnings == null) {
-      return ImmutableSet.of();
-    }
-    return ImmutableSet.copyOf(suppressedWarnings.value());
-  }
-
-  /**
-   * Invokes {@link Elements#getTypeElement(CharSequence)}, throwing {@link TypeNotPresentException}
-   * if it is not accessible in the current compilation.
-   */
-  public TypeElement checkTypePresent(String typeName) {
-    TypeElement type = elements.getTypeElement(typeName);
-    if (type == null) {
-      throw new TypeNotPresentException(typeName, null);
-    }
-    return type;
-  }
-
-  @Override
-  public PackageElement getPackageElement(CharSequence name) {
-    return elements.getPackageElement(name);
-  }
-
-  @Override
-  public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults(
-      AnnotationMirror a) {
-    return elements.getElementValuesWithDefaults(a);
-  }
-
-  @Override
-  public String getDocComment(Element e) {
-    return elements.getDocComment(e);
-  }
-
-  @Override
-  public boolean isDeprecated(Element e) {
-    return elements.isDeprecated(e);
-  }
-
-  @Override
-  public Name getBinaryName(TypeElement type) {
-    return elements.getBinaryName(type);
-  }
-
-  @Override
-  public PackageElement getPackageOf(Element type) {
-    return elements.getPackageOf(type);
-  }
-
-  @Override
-  public List<? extends Element> getAllMembers(TypeElement type) {
-    return elements.getAllMembers(type);
-  }
-
-  @Override
-  public List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
-    return elements.getAllAnnotationMirrors(e);
-  }
-
-  @Override
-  public boolean hides(Element hider, Element hidden) {
-    return elements.hides(hider, hidden);
-  }
-
-  @Override
-  public boolean overrides(
-      ExecutableElement overrider, ExecutableElement overridden, TypeElement type) {
-    return elements.overrides(overrider, overridden, type);
-  }
-
-  @Override
-  public String getConstantExpression(Object value) {
-    return elements.getConstantExpression(value);
-  }
-
-  @Override
-  public void printElements(Writer w, Element... elements) {
-    this.elements.printElements(w, elements);
-  }
-
-  @Override
-  public Name getName(CharSequence cs) {
-    return elements.getName(cs);
-  }
-
-  @Override
-  public boolean isFunctionalInterface(TypeElement type) {
-    return elements.isFunctionalInterface(type);
-  }
-}
diff --git a/java/dagger/internal/codegen/langmodel/DaggerTypes.java b/java/dagger/internal/codegen/langmodel/DaggerTypes.java
deleted file mode 100644
index e588fbd..0000000
--- a/java/dagger/internal/codegen/langmodel/DaggerTypes.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2016 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.langmodel;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.getOnlyElement;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.graph.Traverser;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.squareup.javapoet.ClassName;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.SimpleTypeVisitor8;
-import javax.lang.model.util.Types;
-
-/** Extension of {@link Types} that adds Dagger-specific methods. */
-public final class DaggerTypes implements Types {
-  private final Types types;
-  private final DaggerElements elements;
-
-  @Inject
-  public DaggerTypes(Types types, DaggerElements elements) {
-    this.types = checkNotNull(types);
-    this.elements = checkNotNull(elements);
-  }
-
-  /**
-   * Returns the non-{@link Object} superclass of the type with the proper type parameters. An empty
-   * {@link Optional} is returned if there is no non-{@link Object} superclass.
-   */
-  public Optional<DeclaredType> nonObjectSuperclass(DeclaredType type) {
-    return Optional.ofNullable(MoreTypes.nonObjectSuperclass(types, elements, type).orNull());
-  }
-
-  /**
-   * Returns the {@linkplain #directSupertypes(TypeMirror) supertype}s of a type in breadth-first
-   * order.
-   */
-  public Iterable<TypeMirror> supertypes(TypeMirror type) {
-    return Traverser.<TypeMirror>forGraph(this::directSupertypes).breadthFirst(type);
-  }
-
-  /**
-   * Returns {@code type}'s single type argument.
-   *
-   * <p>For example, if {@code type} is {@code List<Number>} this will return {@code Number}.
-   *
-   * @throws IllegalArgumentException if {@code type} is not a declared type or has zero or more
-   *     than one type arguments.
-   */
-  public TypeMirror unwrapType(TypeMirror type) {
-    TypeMirror unwrapped = unwrapTypeOrDefault(type, null);
-    checkArgument(unwrapped != null, "%s is a raw type", type);
-    return unwrapped;
-  }
-
-  /**
-   * Returns {@code type}'s single type argument, if one exists, or {@link Object} if not.
-   *
-   * <p>For example, if {@code type} is {@code List<Number>} this will return {@code Number}.
-   *
-   * @throws IllegalArgumentException if {@code type} is not a declared type or has more than one
-   *     type argument.
-   */
-  public TypeMirror unwrapTypeOrObject(TypeMirror type) {
-    return unwrapTypeOrDefault(type, elements.getTypeElement(Object.class).asType());
-  }
-
-  private TypeMirror unwrapTypeOrDefault(TypeMirror type, TypeMirror defaultType) {
-    DeclaredType declaredType = MoreTypes.asDeclared(type);
-    TypeElement typeElement = MoreElements.asType(declaredType.asElement());
-    checkArgument(
-        !typeElement.getTypeParameters().isEmpty(),
-        "%s does not have a type parameter",
-        typeElement.getQualifiedName());
-    return getOnlyElement(declaredType.getTypeArguments(), defaultType);
-  }
-
-  /**
-   * Returns {@code type} wrapped in {@code wrappingClass}.
-   *
-   * <p>For example, if {@code type} is {@code List<Number>} and {@code wrappingClass} is {@code
-   * Set.class}, this will return {@code Set<List<Number>>}.
-   */
-  public DeclaredType wrapType(TypeMirror type, Class<?> wrappingClass) {
-    return types.getDeclaredType(elements.getTypeElement(wrappingClass), type);
-  }
-
-  /**
-   * Returns {@code type}'s single type argument wrapped in {@code wrappingClass}.
-   *
-   * <p>For example, if {@code type} is {@code List<Number>} and {@code wrappingClass} is {@code
-   * Set.class}, this will return {@code Set<Number>}.
-   *
-   * <p>If {@code type} has no type parameters, returns a {@link TypeMirror} for {@code
-   * wrappingClass} as a raw type.
-   *
-   * @throws IllegalArgumentException if {@code} has more than one type argument.
-   */
-  public DeclaredType rewrapType(TypeMirror type, Class<?> wrappingClass) {
-    List<? extends TypeMirror> typeArguments = MoreTypes.asDeclared(type).getTypeArguments();
-    TypeElement wrappingType = elements.getTypeElement(wrappingClass);
-    switch (typeArguments.size()) {
-      case 0:
-        return getDeclaredType(wrappingType);
-      case 1:
-        return getDeclaredType(wrappingType, getOnlyElement(typeArguments));
-      default:
-        throw new IllegalArgumentException(type + " has more than 1 type argument");
-    }
-  }
-
-  /**
-   * Returns a publicly accessible type based on {@code type}:
-   *
-   * <ul>
-   *   <li>If {@code type} is publicly accessible, returns it.
-   *   <li>If not, but {@code type}'s raw type is publicly accessible, returns the raw type.
-   *   <li>Otherwise returns {@link Object}.
-   * </ul>
-   */
-  public TypeMirror publiclyAccessibleType(TypeMirror type) {
-    return accessibleType(
-        type, Accessibility::isTypePubliclyAccessible, Accessibility::isRawTypePubliclyAccessible);
-  }
-
-  /**
-   * Returns an accessible type in {@code requestingClass}'s package based on {@code type}:
-   *
-   * <ul>
-   *   <li>If {@code type} is accessible from the package, returns it.
-   *   <li>If not, but {@code type}'s raw type is accessible from the package, returns the raw type.
-   *   <li>Otherwise returns {@link Object}.
-   * </ul>
-   */
-  public TypeMirror accessibleType(TypeMirror type, ClassName requestingClass) {
-    return accessibleType(
-        type,
-        t -> Accessibility.isTypeAccessibleFrom(t, requestingClass.packageName()),
-        t -> Accessibility.isRawTypeAccessible(t, requestingClass.packageName()));
-  }
-
-  private TypeMirror accessibleType(
-      TypeMirror type,
-      Predicate<TypeMirror> accessibilityPredicate,
-      Predicate<TypeMirror> rawTypeAccessibilityPredicate) {
-    if (accessibilityPredicate.test(type)) {
-      return type;
-    } else if (type.getKind().equals(TypeKind.DECLARED)
-        && rawTypeAccessibilityPredicate.test(type)) {
-      return getDeclaredType(MoreTypes.asTypeElement(type));
-    } else {
-      return elements.getTypeElement(Object.class).asType();
-    }
-  }
-
-  /**
-   * Throws {@link TypeNotPresentException} if {@code type} is an {@link
-   * javax.lang.model.type.ErrorType}.
-   */
-  public static void checkTypePresent(TypeMirror type) {
-    type.accept(
-        // TODO(ronshapiro): Extract a base class that visits all components of a complex type
-        // and put it in auto.common
-        new SimpleTypeVisitor8<Void, Void>() {
-          @Override
-          public Void visitArray(ArrayType arrayType, Void p) {
-            return arrayType.getComponentType().accept(this, p);
-          }
-
-          @Override
-          public Void visitDeclared(DeclaredType declaredType, Void p) {
-            declaredType.getTypeArguments().forEach(t -> t.accept(this, p));
-            return null;
-          }
-
-          @Override
-          public Void visitError(ErrorType errorType, Void p) {
-            throw new TypeNotPresentException(type.toString(), null);
-          }
-        },
-        null);
-  }
-
-  private static final ImmutableSet<Class<?>> FUTURE_TYPES =
-      ImmutableSet.of(ListenableFuture.class, FluentFuture.class);
-
-  public static boolean isFutureType(TypeMirror type) {
-    return FUTURE_TYPES.stream().anyMatch(t -> MoreTypes.isTypeOf(t, type));
-  }
-
-  public static boolean hasTypeVariable(TypeMirror type) {
-    return type.accept(
-        new SimpleTypeVisitor8<Boolean, Void>() {
-          @Override
-          public Boolean visitArray(ArrayType arrayType, Void p) {
-            return arrayType.getComponentType().accept(this, p);
-          }
-
-          @Override
-          public Boolean visitDeclared(DeclaredType declaredType, Void p) {
-            return declaredType.getTypeArguments().stream().anyMatch(type -> type.accept(this, p));
-          }
-
-          @Override
-          public Boolean visitTypeVariable(TypeVariable t, Void aVoid) {
-            return true;
-          }
-
-          @Override
-          protected Boolean defaultAction(TypeMirror e, Void aVoid) {
-            return false;
-          }
-        },
-        null);
-  }
-
-  /**
-   * Resolves the type of the given executable element as a member of the given type. This may
-   * resolve type variables to concrete types, etc.
-   */
-  public ExecutableType resolveExecutableType(ExecutableElement element, TypeMirror containerType) {
-    return MoreTypes.asExecutable(asMemberOf(MoreTypes.asDeclared(containerType), element));
-  }
-
-  // Implementation of Types methods, delegating to types.
-
-  @Override
-  public Element asElement(TypeMirror t) {
-    return types.asElement(t);
-  }
-
-  @Override
-  public boolean isSameType(TypeMirror t1, TypeMirror t2) {
-    return types.isSameType(t1, t2);
-  }
-
-  @Override
-  public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
-    return types.isSubtype(t1, t2);
-  }
-
-  @Override
-  public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
-    return types.isAssignable(t1, t2);
-  }
-
-  @Override
-  public boolean contains(TypeMirror t1, TypeMirror t2) {
-    return types.contains(t1, t2);
-  }
-
-  @Override
-  public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
-    return types.isSubsignature(m1, m2);
-  }
-
-  @Override
-  public List<? extends TypeMirror> directSupertypes(TypeMirror t) {
-    return types.directSupertypes(t);
-  }
-
-  @Override
-  public TypeMirror erasure(TypeMirror t) {
-    return types.erasure(t);
-  }
-
-  @Override
-  public TypeElement boxedClass(PrimitiveType p) {
-    return types.boxedClass(p);
-  }
-
-  @Override
-  public PrimitiveType unboxedType(TypeMirror t) {
-    return types.unboxedType(t);
-  }
-
-  @Override
-  public TypeMirror capture(TypeMirror t) {
-    return types.capture(t);
-  }
-
-  @Override
-  public PrimitiveType getPrimitiveType(TypeKind kind) {
-    return types.getPrimitiveType(kind);
-  }
-
-  @Override
-  public NullType getNullType() {
-    return types.getNullType();
-  }
-
-  @Override
-  public NoType getNoType(TypeKind kind) {
-    return types.getNoType(kind);
-  }
-
-  @Override
-  public ArrayType getArrayType(TypeMirror componentType) {
-    return types.getArrayType(componentType);
-  }
-
-  @Override
-  public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) {
-    return types.getWildcardType(extendsBound, superBound);
-  }
-
-  @Override
-  public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
-    return types.getDeclaredType(typeElem, typeArgs);
-  }
-
-  @Override
-  public DeclaredType getDeclaredType(
-      DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs) {
-    return types.getDeclaredType(containing, typeElem, typeArgs);
-  }
-
-  @Override
-  public TypeMirror asMemberOf(DeclaredType containing, Element element) {
-    return types.asMemberOf(containing, element);
-  }
-}
diff --git a/java/dagger/internal/codegen/package-info.java b/java/dagger/internal/codegen/package-info.java
deleted file mode 100644
index c8cc404..0000000
--- a/java/dagger/internal/codegen/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-@CheckReturnValue
-package dagger.internal.codegen;
-
-import com.google.errorprone.annotations.CheckReturnValue;
diff --git a/java/dagger/internal/codegen/serialization/BUILD b/java/dagger/internal/codegen/serialization/BUILD
deleted file mode 100644
index 2bc02b4..0000000
--- a/java/dagger/internal/codegen/serialization/BUILD
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2019 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.
-
-# Description:
-#    Serialized forms of types used in the Dagger processor.
-
-package(default_visibility = ["//:src"])
-
-proto_library(
-    name = "serialization_proto",
-    srcs = ["serialization.proto"],
-    visibility = ["//visibility:private"],
-)
-
-java_proto_library(
-    name = "serialization_java_proto",
-    visibility = ["//visibility:private"],
-    deps = [":serialization_proto"],
-)
-
-java_library(
-    name = "serialization",
-    srcs = glob(["*.java"]),
-    exports = [":serialization_java_proto"],
-    deps = [
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/protobuf",
-    ],
-)
diff --git a/java/dagger/internal/codegen/serialization/ProtoSerialization.java b/java/dagger/internal/codegen/serialization/ProtoSerialization.java
deleted file mode 100644
index 1449e9d..0000000
--- a/java/dagger/internal/codegen/serialization/ProtoSerialization.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 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.serialization;
-
-import static com.google.common.io.BaseEncoding.base64;
-
-import com.google.common.io.BaseEncoding;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Message;
-import com.squareup.javapoet.CodeBlock;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-
-/**
- * Serializes and deserializes {@link Message}s using {@link BaseEncoding#base64()} for use in
- * annotation values.
- */
-public final class ProtoSerialization {
-  /** Returns a {@link CodeBlock} of {@code message} serialized as a String. */
-  public static CodeBlock toAnnotationValue(Message message) {
-    return CodeBlock.of("$S", base64().encode(message.toByteArray()));
-  }
-
-  /**
-   * Returns a {@link Message T} from the deserialized the String {@code value}.
-   *
-   * @throws IllegalArgumentException if {@code value} represents an {@link AnnotationValue} who's
-   *     type is not {@link String}
-   */
-  public static <T extends Message> T fromAnnotationValue(
-      AnnotationValue value, T defaultInstance) {
-    byte[] bytes = base64().decode(value.accept(STRING_VALUE, null));
-    Message message;
-    try {
-      message = defaultInstance.getParserForType().parseFrom(bytes);
-    } catch (InvalidProtocolBufferException e) {
-      throw new InconsistentSerializedProtoException(e);
-    }
-    @SuppressWarnings("unchecked") // guaranteed by proto API
-    T t = (T) message;
-    return t;
-  }
-
-  private static final AnnotationValueVisitor<String, Void> STRING_VALUE =
-      new SimpleAnnotationValueVisitor8<String, Void>() {
-        @Override
-        public String visitString(String s, Void ignored) {
-          return s;
-        }
-
-        @Override
-        protected String defaultAction(Object o, Void ignored) {
-          throw new IllegalArgumentException(o + " is not a String");
-        }
-      };
-
-  /**
-   * An exception thrown when the proto that's serialized in a compiled subcomponent implementation
-   * is from a different version than the current compiler's.
-   */
-  public static final class InconsistentSerializedProtoException extends RuntimeException {
-    InconsistentSerializedProtoException(Throwable cause) {
-      super(cause);
-    }
-  }
-}
diff --git a/java/dagger/internal/codegen/serialization/serialization.proto b/java/dagger/internal/codegen/serialization/serialization.proto
deleted file mode 100644
index e6c9577..0000000
--- a/java/dagger/internal/codegen/serialization/serialization.proto
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-// Serialized forms of types used in the Dagger processor. The wire format of
-// these types is not guaranteed to remain compatible over time; serialization
-// is only expected to function correctly within an individual version of the
-// Dagger processor.
-
-syntax = "proto3";
-
-package dagger.internal.codegen.serialization;
-option java_package = "dagger.internal.codegen.serialization";
-option java_multiple_files = true;
-
-// TODO(ronshapiro): consider exposing some of these in
-// dagger.model.serialization
-
-// Serialized form of `dagger.internal.codegen.BindingRequest`
-message BindingRequestProto {
-  KeyProto key = 1;
-  RequestKindWrapper.RequestKind request_kind = 2;
-  FrameworkTypeWrapper.FrameworkType framework_type = 3;
-}
-
-message RequestKindWrapper {
-  // Serialized form of `dagger.model.RequestKind`
-  enum RequestKind {
-    UNKNOWN = 0;
-    INSTANCE = 1;
-    PROVIDER = 2;
-    LAZY = 3;
-    PROVIDER_OF_LAZY = 4;
-    MEMBERS_INJECTION = 5;
-    PRODUCER = 6;
-    PRODUCED = 7;
-    FUTURE = 8;
-  }
-}
-
-message FrameworkTypeWrapper {
-  // Serialized form of `dagger.internal.codegen.FrameworkType`
-  enum FrameworkType {
-    UNKNOWN = 0;
-    PROVIDER = 1;
-    PRODUCER_NODE = 2;
-  }
-}
-
-// Serialized form of `dagger.model.Key`
-message KeyProto {
-  TypeProto type = 1;
-  AnnotationProto qualifier = 2;
-  MultibindingContributionIdentifier multibinding_contribution_identifier =
-      3;
-
-  // Serialized form of `dagger.model.Key.MultibindingContributionIdentifier`
-  message MultibindingContributionIdentifier {
-    string module = 1;
-    string binding_element = 2;
-  }
-}
-
-// Serialized form of `javax.lang.model.type.TypeMirror`
-message TypeProto {
-  PrimitiveKind primitive_kind = 1;
-
-  // The qualified name of the type. Absent if this is an inner type.
-  string qualified_name = 2;
-
-  // The enclosing type if this is an inner type, otherwise absent.
-  TypeProto enclosing_type = 3;
-
-  // Simple name of the type if this is an inner type, otherwise absent.
-  string simple_name = 4;
-
-  repeated TypeProto type_arguments = 5;
-
-  message Wildcard {
-    TypeProto extends_bound = 1;
-    TypeProto super_bound = 2;
-  }
-  Wildcard wildcard = 6;
-
-  int32 array_dimensions = 7;
-
-  // Kinds of primitive types
-  enum PrimitiveKind {
-    UNKNOWN = 0;
-    BOOLEAN = 1;
-    BYTE = 2;
-    SHORT = 3;
-    CHAR = 4;
-    INT = 5;
-    FLOAT = 6;
-    LONG = 7;
-    DOUBLE = 8;
-  }
-}
-
-// Serialized form of `javax.lang.model.element.AnnotationMirror`
-message AnnotationProto {
-  TypeProto annotation_type = 1;
-  map<string, AnnotationValueProto> values = 2;
-}
-
-// Serialized form of `javax.lang.model.element.AnnotationValue`
-message AnnotationValueProto {
-  Kind kind = 1;
-  bool boolean_value = 2;
-  int32 int_value = 3;
-  int64 long_value = 4;
-  float float_value = 5;
-  double double_value = 6;
-  string string_value = 7;
-  TypeProto class_literal = 8;
-  TypeProto enum_type = 9;
-  string enum_name = 10;
-  AnnotationProto nested_annotation = 11;
-
-  repeated AnnotationValueProto array_values = 12;
-
-  // The type of annotation value
-  enum Kind {
-    UNKNOWN = 0;
-    BOOLEAN = 1;
-    BYTE = 2;
-    SHORT = 3;
-    CHAR = 4;
-    INT = 5;
-    FLOAT = 6;
-    LONG = 7;
-    DOUBLE = 8;
-    STRING = 9;
-    CLASS_LITERAL = 10;
-    ENUM = 11;
-    ANNOTATION = 12;
-    ARRAY = 13;
-  }
-}
-
-// Serialized form of `dagger.internal.codegen.ComponentRequirement`
-message ComponentRequirementProto {
-  oneof requirement {
-    TypeProto dependency = 1;
-    TypeProto module = 2;
-    BoundInstanceRequirement bound_instance = 3;
-  }
-
-  message BoundInstanceRequirement {
-    KeyProto key = 1;
-    bool nullable = 2;
-    string variable_name = 3;
-  }
-}
diff --git a/java/dagger/internal/doc-files/ReferenceReleasingProvider-statemachine.png b/java/dagger/internal/doc-files/ReferenceReleasingProvider-statemachine.png
deleted file mode 100644
index 8195dc0..0000000
--- a/java/dagger/internal/doc-files/ReferenceReleasingProvider-statemachine.png
+++ /dev/null
Binary files differ
diff --git a/java/dagger/model/BUILD b/java/dagger/model/BUILD
deleted file mode 100644
index 5fe0db3..0000000
--- a/java/dagger/model/BUILD
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Dagger's core APIs exposed for plugins
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-
-INTERNAL_PROXIES = ["BindingGraphProxies.java"]
-
-filegroup(
-    name = "model-srcs",
-    srcs = glob(
-        ["*.java"],
-        exclude = INTERNAL_PROXIES,
-    ),
-)
-
-java_library(
-    name = "model",
-    srcs = [":model-srcs"],
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen:jdk-and-guava-extras",
-        "//java/dagger/producers",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
-
-java_library(
-    name = "internal-proxies",
-    srcs = INTERNAL_PROXIES,
-    tags = ["maven:merged"],
-    deps = [
-        ":model",
-        "@google_bazel_common//third_party/java/guava",
-    ],
-)
diff --git a/java/dagger/model/Binding.java b/java/dagger/model/Binding.java
deleted file mode 100644
index 81aba00..0000000
--- a/java/dagger/model/Binding.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 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.model;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.model.BindingGraph.MaybeBinding;
-import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * The association between a {@link Key} and the way in which instances of the key are provided.
- * Includes any {@linkplain DependencyRequest dependencies} that are needed in order to provide the
- * instances.
- *
- * <p>If a binding is owned by more than one component, there is one {@code Binding} for every
- * owning component.
- */
-public interface Binding extends MaybeBinding {
-  @Override
-  ComponentPath componentPath();
-
-  /** @deprecated This always returns {@code Optional.of(this)}. */
-  @Override
-  @Deprecated
-  default Optional<Binding> binding() {
-    return Optional.of(this);
-  }
-  /**
-   * The dependencies of this binding. The order of the dependencies corresponds to the order in
-   * which they will be injected when the binding is requested.
-   */
-  ImmutableSet<DependencyRequest> dependencies();
-
-  /**
-   * The {@link Element} that declares this binding. Absent for {@linkplain BindingKind binding
-   * kinds} that are not always declared by exactly one element.
-   *
-   * <p>For example, consider {@link BindingKind#MULTIBOUND_SET}. A component with many
-   * {@code @IntoSet} bindings for the same key will have a synthetic binding that depends on all
-   * contributions, but with no identifiying binding element. A {@code @Multibinds} method will also
-   * contribute a synthetic binding, but since multiple {@code @Multibinds} methods can coexist in
-   * the same component (and contribute to one single binding), it has no binding element.
-   */
-  Optional<Element> bindingElement();
-
-  /**
-   * The {@link TypeElement} of the module which contributes this binding. Absent for bindings that
-   * have no {@link #bindingElement() binding element}.
-   */
-  Optional<TypeElement> contributingModule();
-
-  /**
-   * Returns {@code true} if using this binding requires an instance of the {@link
-   * #contributingModule()}.
-   */
-  boolean requiresModuleInstance();
-
-  /** The scope of this binding if it has one. */
-  Optional<Scope> scope();
-
-  /**
-   * Returns {@code true} if this binding may provide {@code null} instead of an instance of {@link
-   * #key()}. Nullable bindings cannot be requested from {@linkplain DependencyRequest#isNullable()
-   * non-nullable dependency requests}.
-   */
-  boolean isNullable();
-
-  /** Returns {@code true} if this is a production binding, e.g. an {@code @Produces} method. */
-  boolean isProduction();
-
-  /** The kind of binding this instance represents. */
-  BindingKind kind();
-
-}
diff --git a/java/dagger/model/BindingGraph.java b/java/dagger/model/BindingGraph.java
deleted file mode 100644
index 748bf38..0000000
--- a/java/dagger/model/BindingGraph.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2016 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.model;
-
-import static com.google.common.collect.Sets.intersection;
-import static com.google.common.graph.Graphs.inducedSubgraph;
-import static com.google.common.graph.Graphs.reachableNodes;
-import static com.google.common.graph.Graphs.transpose;
-import static dagger.internal.codegen.DaggerStreams.instancesOf;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSetMultimap;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.graph.EndpointPair;
-import com.google.common.graph.ImmutableNetwork;
-import com.google.common.graph.MutableNetwork;
-import com.google.common.graph.Network;
-import com.google.common.graph.NetworkBuilder;
-import dagger.Module;
-import java.util.Optional;
-import java.util.stream.Stream;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-
-/**
- * A graph of bindings, dependency requests, and components.
- *
- * <p>A {@link BindingGraph} represents one of the following:
- *
- * <ul>
- *   <li>an entire component hierarchy rooted at a {@link dagger.Component} or {@link
- *       dagger.producers.ProductionComponent}
- *   <li>a partial component hierarchy rooted at a {@link dagger.Subcomponent} or {@link
- *       dagger.producers.ProductionSubcomponent} (only when {@code
- *       -Adagger.experimentalAheadOfTimeSubcomponents=enabled} is passed to the compiler)
- *   <li>the bindings installed by a {@link Module} or {@link dagger.producers.ProducerModule},
- *       including all subcomponents generated by {@link Module#subcomponents()} ()} and {@link
- *       dagger.producers.ProducerModule#subcomponents()} ()}
- * </ul>
- *
- * In the case of a {@link BindingGraph} representing a module, the root {@link ComponentNode} will
- * actually represent the module type. The graph will also be a {@linkplain #isFullBindingGraph()
- * full binding graph}, which means it will contain all bindings in all modules, as well as nodes
- * for their dependencies. Otherwise it will contain only bindings that are reachable from at least
- * one {@linkplain #entryPointEdges() entry point}.
- *
- * <h3>Nodes</h3>
- *
- * <p>There is a <b>{@link Binding}</b> for each owned binding in the graph. If a binding is owned
- * by more than one component, there is one binding object for that binding for every owning
- * component.
- *
- * <p>There is a <b>{@linkplain ComponentNode component node}</b> (without a binding) for each
- * component in the graph.
- *
- * <h3>Edges</h3>
- *
- * <p>There is a <b>{@linkplain DependencyEdge dependency edge}</b> for each dependency request in
- * the graph. Its target node is the binding for the binding that satisfies the request. For entry
- * point dependency requests, the source node is the component node for the component for which it
- * is an entry point. For other dependency requests, the source node is the binding for the binding
- * that contains the request.
- *
- * <p>There is a <b>subcomponent edge</b> for each parent-child component relationship in the graph.
- * The target node is the component node for the child component. For subcomponents defined by a
- * {@linkplain SubcomponentCreatorBindingEdge subcomponent creator binding} (either a method on the
- * component or a set of {@code @Module.subcomponents} annotation values), the source node is the
- * binding for the {@code @Subcomponent.Builder} type. For subcomponents defined by {@linkplain
- * ChildFactoryMethodEdge subcomponent factory methods}, the source node is the component node for
- * the parent.
- *
- * <p><b>Note that this API is experimental and will change.</b>
- */
-@AutoValue
-public abstract class BindingGraph {
-
-  static BindingGraph create(Network<Node, Edge> network, boolean isFullBindingGraph) {
-    return new AutoValue_BindingGraph(ImmutableNetwork.copyOf(network), isFullBindingGraph);
-  }
-
-  BindingGraph() {}
-
-  /** Returns the graph in its {@link Network} representation. */
-  public abstract ImmutableNetwork<Node, Edge> network();
-
-  @Override
-  public final String toString() {
-    return network().toString();
-  }
-
-  /**
-   * Returns {@code true} if this graph was constructed from a module for full binding graph
-   * validation.
-   *
-   * @deprecated use {@link #isFullBindingGraph()} to tell if this is a full binding graph, or
-   *     {@link ComponentNode#isRealComponent() rootComponentNode().isRealComponent()} to tell if
-   *     the root component node is really a component or derived from a module. Dagger can generate
-   *     full binding graphs for components and subcomponents as well as modules.
-   */
-  @Deprecated
-  public final boolean isModuleBindingGraph() {
-    return !rootComponentNode().isRealComponent();
-  }
-
-  /**
-   * Returns {@code true} if this is a full binding graph, which contains all bindings installed in
-   * the component, or {@code false} if it is a reachable binding graph, which contains only
-   * bindings that are reachable from at least one {@linkplain #entryPointEdges() entry point}.
-   *
-   * @see <a href="https://dagger.dev/compiler-options#full-binding-graph-validation">Full binding
-   *     graph validation</a>
-   */
-  public abstract boolean isFullBindingGraph();
-
-  /**
-   * Returns {@code true} if the {@link #rootComponentNode()} is a subcomponent. This occurs in
-   * ahead-of-time-subcomponents mode.
-   *
-   * @deprecated use {@link ComponentNode#isSubcomponent() rootComponentNode().isSubcomponent()}
-   *     instead
-   */
-  @Deprecated
-  public final boolean isPartialBindingGraph() {
-    return rootComponentNode().isSubcomponent();
-  }
-
-  /** Returns the bindings. */
-  public final ImmutableSet<Binding> bindings() {
-    return nodes(Binding.class);
-  }
-
-  /** Returns the bindings for a key. */
-  public final ImmutableSet<Binding> bindings(Key key) {
-    return nodes(Binding.class).stream()
-        .filter(binding -> binding.key().equals(key))
-        .collect(toImmutableSet());
-  }
-
-  /** Returns the nodes that represent missing bindings. */
-  public final ImmutableSet<MissingBinding> missingBindings() {
-    return nodes(MissingBinding.class);
-  }
-
-  /** Returns the component nodes. */
-  public final ImmutableSet<ComponentNode> componentNodes() {
-    return nodes(ComponentNode.class);
-  }
-
-  /** Returns the component node for a component. */
-  public final Optional<ComponentNode> componentNode(ComponentPath component) {
-    return componentNodes().stream()
-        .filter(node -> node.componentPath().equals(component))
-        .findFirst();
-  }
-
-  /** Returns the component nodes for a component. */
-  public final ImmutableSet<ComponentNode> componentNodes(TypeElement component) {
-    return componentNodes().stream()
-        .filter(node -> node.componentPath().currentComponent().equals(component))
-        .collect(toImmutableSet());
-  }
-
-  /** Returns the component node for the root component. */
-  public final ComponentNode rootComponentNode() {
-    return componentNodes().stream()
-        .filter(node -> node.componentPath().atRoot())
-        .findFirst()
-        .get();
-  }
-
-  /** Returns the dependency edges. */
-  public final ImmutableSet<DependencyEdge> dependencyEdges() {
-    return dependencyEdgeStream().collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the dependency edges for the dependencies of a binding. For valid graphs, each {@link
-   * DependencyRequest} will map to a single {@link DependencyEdge}. When conflicting bindings exist
-   * for a key, the multimap will have several edges for that {@link DependencyRequest}. Graphs that
-   * have no binding for a key will have an edge whose {@linkplain EndpointPair#target() target
-   * node} is a {@link MissingBinding}.
-   */
-  public final ImmutableSetMultimap<DependencyRequest, DependencyEdge> dependencyEdges(
-      Binding binding) {
-    return dependencyEdgeStream(binding)
-        .collect(toImmutableSetMultimap(DependencyEdge::dependencyRequest, edge -> edge));
-  }
-
-  /** Returns the dependency edges for a dependency request. */
-  public final ImmutableSet<DependencyEdge> dependencyEdges(DependencyRequest dependencyRequest) {
-    return dependencyEdgeStream()
-        .filter(edge -> edge.dependencyRequest().equals(dependencyRequest))
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the dependency edges for the entry points of a given {@code component}. Each edge's
-   * source node is that component's component node.
-   */
-  public final ImmutableSet<DependencyEdge> entryPointEdges(ComponentPath component) {
-    return dependencyEdgeStream(componentNode(component).get()).collect(toImmutableSet());
-  }
-
-  private Stream<DependencyEdge> dependencyEdgeStream(Node node) {
-    return network().outEdges(node).stream().flatMap(instancesOf(DependencyEdge.class));
-  }
-
-  /**
-   * Returns the dependency edges for all entry points for all components and subcomponents. Each
-   * edge's source node is a component node.
-   */
-  public final ImmutableSet<DependencyEdge> entryPointEdges() {
-    return entryPointEdgeStream().collect(toImmutableSet());
-  }
-
-  /** Returns the binding or missing binding nodes that directly satisfy entry points. */
-  public final ImmutableSet<MaybeBinding> entryPointBindings() {
-    return entryPointEdgeStream()
-        .map(edge -> (MaybeBinding) network().incidentNodes(edge).target())
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the edges for entry points that transitively depend on a binding or missing binding for
-   * a key.
-   */
-  public final ImmutableSet<DependencyEdge> entryPointEdgesDependingOnBinding(
-      MaybeBinding binding) {
-    ImmutableNetwork<Node, DependencyEdge> dependencyGraph = dependencyGraph();
-    Network<Node, DependencyEdge> subgraphDependingOnBinding =
-        inducedSubgraph(
-            dependencyGraph, reachableNodes(transpose(dependencyGraph).asGraph(), binding));
-    return intersection(entryPointEdges(), subgraphDependingOnBinding.edges()).immutableCopy();
-  }
-
-  /** Returns the bindings that directly request a given binding as a dependency. */
-  public final ImmutableSet<Binding> requestingBindings(MaybeBinding binding) {
-    return network().predecessors(binding).stream()
-        .flatMap(instancesOf(Binding.class))
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the bindings that a given binding directly request as a dependency. Does not include
-   * any {@link MissingBinding}s.
-   *
-   * @see #requestedMaybeMissingBindings(Binding)
-   */
-  public final ImmutableSet<Binding> requestedBindings(Binding binding) {
-    return network().successors(binding).stream()
-        .flatMap(instancesOf(Binding.class))
-        .collect(toImmutableSet());
-  }
-
-  /**
-   * Returns the bindings or missing bindings that a given binding directly requests as a
-   * dependency.
-   *
-   * @see #requestedBindings(Binding)
-   */
-  public final ImmutableSet<MaybeBinding> requestedMaybeMissingBindings(Binding binding) {
-    return network().successors(binding).stream()
-        .flatMap(instancesOf(MaybeBinding.class))
-        .collect(toImmutableSet());
-  }
-
-  /** Returns a subnetwork that contains all nodes but only {@link DependencyEdge}s. */
-  // TODO(dpb): Make public. Cache.
-  private ImmutableNetwork<Node, DependencyEdge> dependencyGraph() {
-    MutableNetwork<Node, DependencyEdge> dependencyGraph =
-        NetworkBuilder.from(network())
-            .expectedNodeCount(network().nodes().size())
-            .expectedEdgeCount((int) dependencyEdgeStream().count())
-            .build();
-    network().nodes().forEach(dependencyGraph::addNode); // include disconnected nodes
-    dependencyEdgeStream()
-        .forEach(
-            edge -> {
-              EndpointPair<Node> endpoints = network().incidentNodes(edge);
-              dependencyGraph.addEdge(endpoints.source(), endpoints.target(), edge);
-            });
-    return ImmutableNetwork.copyOf(dependencyGraph);
-  }
-
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  private <N extends Node> ImmutableSet<N> nodes(Class<N> clazz) {
-    return (ImmutableSet) nodesByClass().get(clazz);
-  }
-
-  private static final ImmutableSet<Class<? extends Node>> NODE_TYPES =
-      ImmutableSet.of(Binding.class, MissingBinding.class, ComponentNode.class);
-
-  @Memoized
-  ImmutableSetMultimap<Class<? extends Node>, ? extends Node> nodesByClass() {
-    return network().nodes().stream()
-        .collect(
-            toImmutableSetMultimap(
-                node ->
-                    NODE_TYPES.stream().filter(clazz -> clazz.isInstance(node)).findFirst().get(),
-                node -> node));
-  }
-
-  private Stream<DependencyEdge> dependencyEdgeStream() {
-    return network().edges().stream().flatMap(instancesOf(DependencyEdge.class));
-  }
-
-  private Stream<DependencyEdge> entryPointEdgeStream() {
-    return dependencyEdgeStream().filter(DependencyEdge::isEntryPoint);
-  }
-
-  /**
-   * An edge in the binding graph. Either a {@link DependencyEdge}, a {@link
-   * ChildFactoryMethodEdge}, or a {@link SubcomponentCreatorBindingEdge}.
-   */
-  public interface Edge {}
-
-  /**
-   * An edge that represents a dependency on a binding.
-   *
-   * <p>Because one {@link DependencyRequest} may represent a dependency from two bindings (e.g., a
-   * dependency of {@code Foo<String>} and {@code Foo<Number>} may have the same key and request
-   * element), this class does not override {@link #equals(Object)} to use value semantics.
-   *
-   * <p>For entry points, the source node is the {@link ComponentNode} that contains the entry
-   * point. Otherwise the source node is a {@link Binding}.
-   *
-   * <p>For dependencies on missing bindings, the target node is a {@link MissingBinding}. Otherwise
-   * the target node is a {@link Binding}.
-   */
-  public interface DependencyEdge extends Edge {
-    /** The dependency request. */
-    DependencyRequest dependencyRequest();
-
-    /** Returns {@code true} if this edge represents an entry point. */
-    boolean isEntryPoint();
-  }
-
-  /**
-   * An edge that represents a subcomponent factory method linking a parent component to a child
-   * subcomponent.
-   */
-  public interface ChildFactoryMethodEdge extends Edge {
-    /** The subcomponent factory method element. */
-    ExecutableElement factoryMethod();
-  }
-
-  /**
-   * An edge that represents the link between a parent component and a child subcomponent implied by
-   * a subcomponent creator ({@linkplain dagger.Subcomponent.Builder builder} or {@linkplain
-   * dagger.Subcomponent.Factory factory}) binding.
-   *
-   * <p>The {@linkplain com.google.common.graph.EndpointPair#source() source node} of this edge is a
-   * {@link Binding} for the subcomponent creator {@link Key} and the {@linkplain
-   * com.google.common.graph.EndpointPair#target() target node} is a {@link ComponentNode} for the
-   * child subcomponent.
-   */
-  public interface SubcomponentCreatorBindingEdge extends Edge {
-    /**
-     * The modules that {@linkplain Module#subcomponents() declare the subcomponent} that generated
-     * this edge. Empty if the parent component has a subcomponent creator method and there are no
-     * declaring modules.
-     */
-    ImmutableSet<TypeElement> declaringModules();
-  }
-
-  /** A node in the binding graph. Either a {@link Binding} or a {@link ComponentNode}. */
-  // TODO(dpb): Make all the node/edge types top-level.
-  public interface Node {
-    /** The component this node belongs to. */
-    ComponentPath componentPath();
-  }
-
-  /** A node in the binding graph that is either a {@link Binding} or a {@link MissingBinding}. */
-  public interface MaybeBinding extends Node {
-
-    /** The component that owns the binding, or in which the binding is missing. */
-    @Override
-    ComponentPath componentPath();
-
-    /** The key of the binding, or for which there is no binding. */
-    Key key();
-
-    /** The binding, or empty if missing. */
-    Optional<Binding> binding();
-  }
-
-  /** A node in the binding graph that represents a missing binding for a key in a component. */
-  @AutoValue
-  public abstract static class MissingBinding implements MaybeBinding {
-    static MissingBinding create(ComponentPath component, Key key) {
-      return new AutoValue_BindingGraph_MissingBinding(component, key);
-    }
-
-    /** The component in which the binding is missing. */
-    @Override
-    public abstract ComponentPath componentPath();
-
-    /** The key for which there is no binding. */
-    public abstract Key key();
-
-    /** @deprecated This always returns {@code Optional.empty()}. */
-    @Override
-    @Deprecated
-    public final Optional<Binding> binding() {
-      return Optional.empty();
-    }
-
-    @Override
-    public final String toString() {
-      return String.format("missing binding for %s in %s", key(), componentPath());
-    }
-
-    @Memoized
-    @Override
-    public abstract int hashCode();
-
-    @Override
-    public abstract boolean equals(Object o);
-  }
-
-  /**
-   * A <b>component node</b> in the graph. Every entry point {@linkplain DependencyEdge dependency
-   * edge}'s source node is a component node for the component containing the entry point.
-   */
-  public interface ComponentNode extends Node {
-
-    /** The component represented by this node. */
-    @Override
-    ComponentPath componentPath();
-
-    /**
-     * Returns {@code true} if the component is a {@code @Subcomponent} or
-     * {@code @ProductionSubcomponent}.
-     */
-    boolean isSubcomponent();
-
-    /**
-     * Returns {@code true} if the component is a real component, or {@code false} if it is a
-     * fictional component based on a module.
-     */
-    boolean isRealComponent();
-
-    /** The entry points on this component. */
-    ImmutableSet<DependencyRequest> entryPoints();
-
-    /** The scopes declared on this component. */
-    ImmutableSet<Scope> scopes();
-  }
-}
diff --git a/java/dagger/model/BindingGraphProxies.java b/java/dagger/model/BindingGraphProxies.java
deleted file mode 100644
index c450475..0000000
--- a/java/dagger/model/BindingGraphProxies.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 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.model;
-
-import com.google.common.graph.Network;
-import dagger.model.BindingGraph.Edge;
-import dagger.model.BindingGraph.MissingBinding;
-import dagger.model.BindingGraph.Node;
-
-/**
- * Exposes package-private constructors to the {@code dagger.internal.codegen} package. <em>This
- * class should only be used in the Dagger implementation and is not part of any documented
- * API.</em>
- */
-public final class BindingGraphProxies {
-  /** Creates a new {@link BindingGraph}. */
-  public static BindingGraph bindingGraph(Network<Node, Edge> network, boolean isFullBindingGraph) {
-    return BindingGraph.create(network, isFullBindingGraph);
-  }
-
-  /** Creates a new {@link MissingBinding}. */
-  public static MissingBinding missingBindingNode(ComponentPath component, Key key) {
-    return MissingBinding.create(component, key);
-  }
-
-  private BindingGraphProxies() {}
-}
diff --git a/java/dagger/model/BindingKind.java b/java/dagger/model/BindingKind.java
deleted file mode 100644
index 20d7b42..0000000
--- a/java/dagger/model/BindingKind.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 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.model;
-
-/** Represents the different kinds of {@link Binding}s that can exist in a binding graph. */
-public enum BindingKind {
-  /** A binding for an {@link javax.inject.Inject}-annotated constructor. */
-  INJECTION,
-
-  /** A binding for a {@link dagger.Provides}-annotated method. */
-  PROVISION,
-
-  /**
-   * An implicit binding for a {@link dagger.Component}- or {@link
-   * dagger.producers.ProductionComponent}-annotated type.
-   */
-  COMPONENT,
-
-  /**
-   * A binding for a provision method on a component's {@linkplain dagger.Component#dependencies()
-   * dependency}.
-   */
-  COMPONENT_PROVISION,
-
-  /**
-   * A binding for an instance of a component's {@linkplain dagger.Component#dependencies()
-   * dependency}.
-   */
-  COMPONENT_DEPENDENCY,
-
-  /** A binding for a {@link dagger.MembersInjector} of a type. */
-  MEMBERS_INJECTOR,
-
-  /**
-   * A binding for a subcomponent creator (a {@linkplain dagger.Subcomponent.Builder builder} or
-   * {@linkplain dagger.Subcomponent.Factory factory}).
-   *
-   * @since 2.22 (previously named {@code SUBCOMPONENT_BUILDER})
-   */
-  SUBCOMPONENT_CREATOR,
-
-  /** A binding for a {@link dagger.BindsInstance}-annotated builder method. */
-  BOUND_INSTANCE,
-
-  /** A binding for a {@link dagger.producers.Produces}-annotated method. */
-  PRODUCTION,
-
-  /**
-   * A binding for a production method on a production component's {@linkplain
-   * dagger.producers.ProductionComponent#dependencies()} dependency} that returns a {@link
-   * com.google.common.util.concurrent.ListenableFuture} or {@link
-   * com.google.common.util.concurrent.FluentFuture}. Methods on production component dependencies
-   * that don't return a future are considered {@linkplain #COMPONENT_PROVISION component provision
-   * bindings}.
-   */
-  COMPONENT_PRODUCTION,
-
-  /**
-   * A synthetic binding for a multibound set that depends on individual multibinding {@link
-   * #PROVISION} or {@link #PRODUCTION} contributions.
-   */
-  MULTIBOUND_SET,
-
-  /**
-   * A synthetic binding for a multibound map that depends on the individual multibinding {@link
-   * #PROVISION} or {@link #PRODUCTION} contributions.
-   */
-  MULTIBOUND_MAP,
-
-  /**
-   * A synthetic binding for {@code Optional} of a type or a {@link javax.inject.Provider}, {@link
-   * dagger.Lazy}, or {@code Provider} of {@code Lazy} of a type. Generated by a {@link
-   * dagger.BindsOptionalOf} declaration.
-   */
-  OPTIONAL,
-
-  /**
-   * A binding for {@link dagger.Binds}-annotated method that that delegates from requests for one
-   * key to another.
-   */
-  // TODO(dpb,ronshapiro): This name is confusing and could use work. Not all usages of @Binds
-  // bindings are simple delegations and we should have a name that better reflects that
-  DELEGATE,
-
-  /** A binding for a members injection method on a component. */
-  MEMBERS_INJECTION,
-  ;
-
-  /**
-   * Returns {@code true} if this is a kind of multibinding (not a contribution to a multibinding,
-   * but the multibinding itself).
-   */
-  public boolean isMultibinding() {
-    switch (this) {
-      case MULTIBOUND_MAP:
-      case MULTIBOUND_SET:
-        return true;
-
-      default:
-        return false;
-    }
-  }
-}
diff --git a/java/dagger/model/ComponentPath.java b/java/dagger/model/ComponentPath.java
deleted file mode 100644
index 5a74c7a..0000000
--- a/java/dagger/model/ComponentPath.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2018 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.model;
-
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.Iterables.getLast;
-import static java.util.stream.Collectors.joining;
-
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.collect.ImmutableList;
-import javax.lang.model.element.TypeElement;
-
-/** A path containing a component and all of its ancestor components. */
-@AutoValue
-public abstract class ComponentPath {
-  /** Returns a new {@link ComponentPath} from {@code components}. */
-  public static ComponentPath create(Iterable<TypeElement> components) {
-    return new AutoValue_ComponentPath(ImmutableList.copyOf(components));
-  }
-
-  /**
-   * Returns the component types, starting from the {@linkplain #rootComponent() root
-   * component} and ending with the {@linkplain #currentComponent() current component}.
-   */
-  public abstract ImmutableList<TypeElement> components();
-
-  /**
-   * Returns the root {@link dagger.Component}- or {@link
-   * dagger.producers.ProductionComponent}-annotated type
-   */
-  public final TypeElement rootComponent() {
-    return components().get(0);
-  }
-
-  /** Returns the component at the end of the path. */
-  @Memoized
-  public TypeElement currentComponent() {
-    return getLast(components());
-  }
-
-  /**
-   * Returns the parent of the {@linkplain #currentComponent()} current component}.
-   *
-   * @throws IllegalStateException if the current graph is the {@linkplain #atRoot() root component}
-   */
-  public final TypeElement parentComponent() {
-    checkState(!atRoot());
-    return components().reverse().get(1);
-  }
-
-  /**
-   * Returns this path's parent path.
-   *
-   * @throws IllegalStateException if the current graph is the {@linkplain #atRoot() root component}
-   */
-  // TODO(ronshapiro): consider memoizing this
-  public final ComponentPath parent() {
-    checkState(!atRoot());
-    return create(components().subList(0, components().size() - 1));
-  }
-
-  /** Returns the path from the root component to the {@code child} of the current component. */
-  public final ComponentPath childPath(TypeElement child) {
-    return create(ImmutableList.<TypeElement>builder().addAll(components()).add(child).build());
-  }
-
-  /**
-   * Returns {@code true} if the {@linkplain #currentComponent()} current component} is the
-   * {@linkplain #rootComponent()} root component}.
-   */
-  public final boolean atRoot() {
-    return components().size() == 1;
-  }
-
-  @Override
-  public final String toString() {
-    return components().stream().map(TypeElement::getQualifiedName).collect(joining(" → "));
-  }
-
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-}
diff --git a/java/dagger/model/DependencyRequest.java b/java/dagger/model/DependencyRequest.java
deleted file mode 100644
index 607b5ec..0000000
--- a/java/dagger/model/DependencyRequest.java
+++ /dev/null
@@ -1,77 +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.model;
-
-import com.google.auto.value.AutoValue;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.Provides;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.lang.model.element.Element;
-
-/**
- * Represents a request for a {@link Key} at an injection point. For example, parameters to {@link
- * Inject} constructors, {@link Provides} methods, and component methods are all dependency
- * requests.
- *
- * <p id="synthetic">A dependency request is considered to be <em>synthetic</em> if it does not have
- * an {@link Element} in code that requests the key directly. For example, an {@link
- * java.util.concurrent.Executor} is required for all {@code @Produces} methods to run
- * asynchronously even though it is not directly specified as a parameter to the binding method.
- */
-@AutoValue
-public abstract class DependencyRequest {
-  /** The kind of this request. */
-  public abstract RequestKind kind();
-
-  /** The key of this request. */
-  public abstract Key key();
-
-  /**
-   * The element that declares this dependency request. Absent for <a href="#synthetic">synthetic
-   * </a> requests.
-   */
-  public abstract Optional<Element> requestElement();
-
-  /**
-   * Returns {@code true} if this request allows null objects. A request is nullable if it is
-   * has an annotation with "Nullable" as its simple name.
-   */
-  public abstract boolean isNullable();
-
-  /** Returns a new builder of dependency requests. */
-  public static DependencyRequest.Builder builder() {
-    return new AutoValue_DependencyRequest.Builder().isNullable(false);
-  }
-
-  /** A builder of {@link DependencyRequest}s. */
-  @CanIgnoreReturnValue
-  @AutoValue.Builder
-  public abstract static class Builder {
-    public abstract Builder kind(RequestKind kind);
-
-    public abstract Builder key(Key key);
-
-    public abstract Builder requestElement(Element element);
-
-    public abstract Builder isNullable(boolean isNullable);
-
-    @CheckReturnValue
-    public abstract DependencyRequest build();
-  }
-}
diff --git a/java/dagger/model/Key.java b/java/dagger/model/Key.java
deleted file mode 100644
index 03dd41c..0000000
--- a/java/dagger/model/Key.java
+++ /dev/null
@@ -1,286 +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.model;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.stream.Collectors.joining;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Equivalence.Wrapper;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableMap;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.google.errorprone.annotations.CheckReturnValue;
-import com.squareup.javapoet.CodeBlock;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
-
-/**
- * A {@linkplain TypeMirror type} and an optional {@linkplain javax.inject.Qualifier qualifier} that
- * is the lookup key for a binding.
- */
-@AutoValue
-public abstract class Key {
-  /**
-   * A {@link javax.inject.Qualifier} annotation that provides a unique namespace prefix
-   * for the type of this key.
-   */
-  public final Optional<AnnotationMirror> qualifier() {
-    return wrappedQualifier().map(Wrapper::get);
-  }
-
-  /**
-   * The type represented by this key.
-   */
-  public final TypeMirror type() {
-    return wrappedType().get();
-  }
-
-  /**
-   * A {@link javax.inject.Qualifier} annotation that provides a unique namespace prefix
-   * for the type of this key.
-   *
-   * Despite documentation in {@link AnnotationMirror}, equals and hashCode aren't implemented
-   * to represent logical equality, so {@link AnnotationMirrors#equivalence()}
-   * provides this facility.
-   */
-  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedQualifier();
-
-  /**
-   * The type represented by this key.
-   *
-   * As documented in {@link TypeMirror}, equals and hashCode aren't implemented to represent
-   * logical equality, so {@link MoreTypes#equivalence()} wraps this type.
-   */
-  abstract Equivalence.Wrapper<TypeMirror> wrappedType();
-
-  /**
-   * Distinguishes keys for multibinding contributions that share a {@link #type()} and {@link
-   * #qualifier()}.
-   *
-   * <p>Each multibound map and set has a synthetic multibinding that depends on the specific
-   * contributions to that map or set using keys that identify those multibinding contributions.
-   *
-   * <p>Absent except for multibinding contributions.
-   */
-  public abstract Optional<MultibindingContributionIdentifier> multibindingContributionIdentifier();
-
-  /** Returns a {@link Builder} that inherits the properties of this key. */
-  public abstract Builder toBuilder();
-
-  // The main hashCode/equality bottleneck is in MoreTypes.equivalence(). It's possible that we can
-  // avoid this by tuning that method. Perhaps we can also avoid the issue entirely by interning all
-  // Keys
-  @Memoized
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object o);
-
-  /**
-   * Returns a String rendering of an {@link AnnotationMirror} that includes attributes in the order
-   * defined in the annotation type. This will produce the same output for {@linkplain
-   * AnnotationMirrors#equivalence() equal} {@link AnnotationMirror}s even if default values are
-   * omitted or their attributes were written in different orders, e.g. {@code @A(b = "b", c = "c")}
-   * and {@code @A(c = "c", b = "b", attributeWithDefaultValue = "default value")}.
-   */
-  // TODO(ronshapiro): move this to auto-common
-  private static String stableAnnotationMirrorToString(AnnotationMirror qualifier) {
-    StringBuilder builder = new StringBuilder("@").append(qualifier.getAnnotationType());
-    ImmutableMap<ExecutableElement, AnnotationValue> elementValues =
-        AnnotationMirrors.getAnnotationValuesWithDefaults(qualifier);
-    if (!elementValues.isEmpty()) {
-      ImmutableMap.Builder<String, String> namedValuesBuilder = ImmutableMap.builder();
-      elementValues.forEach(
-          (key, value) ->
-              namedValuesBuilder.put(
-                  key.getSimpleName().toString(), stableAnnotationValueToString(value)));
-      ImmutableMap<String, String> namedValues = namedValuesBuilder.build();
-      builder.append('(');
-      if (namedValues.size() == 1 && namedValues.containsKey("value")) {
-        // Omit "value ="
-        builder.append(namedValues.get("value"));
-      } else {
-        builder.append(Joiner.on(", ").withKeyValueSeparator("=").join(namedValues));
-      }
-      builder.append(')');
-    }
-    return builder.toString();
-  }
-
-  private static String stableAnnotationValueToString(AnnotationValue annotationValue) {
-    return annotationValue.accept(
-        new SimpleAnnotationValueVisitor8<String, Void>() {
-          @Override
-          protected String defaultAction(Object value, Void ignore) {
-            return value.toString();
-          }
-
-          @Override
-          public String visitString(String value, Void ignore) {
-            return CodeBlock.of("$S", value).toString();
-          }
-
-          @Override
-          public String visitAnnotation(AnnotationMirror value, Void ignore) {
-            return stableAnnotationMirrorToString(value);
-          }
-
-          @Override
-          public String visitArray(List<? extends AnnotationValue> value, Void ignore) {
-            return value.stream()
-                .map(Key::stableAnnotationValueToString)
-                .collect(joining(", ", "{", "}"));
-          }
-        },
-        null);
-  }
-
-  @Override
-  public final String toString() {
-    return Joiner.on(' ')
-        .skipNulls()
-        .join(
-            qualifier().map(Key::stableAnnotationMirrorToString).orElse(null),
-            type(),
-            multibindingContributionIdentifier().orElse(null));
-  }
-
-  /** Returns a builder for {@link Key}s. */
-  public static Builder builder(TypeMirror type) {
-    return new AutoValue_Key.Builder().type(type);
-  }
-
-  /** A builder for {@link Key}s. */
-  @CanIgnoreReturnValue
-  @AutoValue.Builder
-  public abstract static class Builder {
-    abstract Builder wrappedType(Equivalence.Wrapper<TypeMirror> wrappedType);
-
-    public final Builder type(TypeMirror type) {
-      return wrappedType(MoreTypes.equivalence().wrap(checkNotNull(type)));
-    }
-
-    abstract Builder wrappedQualifier(
-        Optional<Equivalence.Wrapper<AnnotationMirror>> wrappedQualifier);
-
-    abstract Builder wrappedQualifier(Equivalence.Wrapper<AnnotationMirror> wrappedQualifier);
-
-    public final Builder qualifier(AnnotationMirror qualifier) {
-      return wrappedQualifier(AnnotationMirrors.equivalence().wrap(checkNotNull(qualifier)));
-    }
-
-    public final Builder qualifier(Optional<AnnotationMirror> qualifier) {
-      return wrappedQualifier(checkNotNull(qualifier).map(AnnotationMirrors.equivalence()::wrap));
-    }
-
-    public abstract Builder multibindingContributionIdentifier(
-        Optional<MultibindingContributionIdentifier> identifier);
-
-    public abstract Builder multibindingContributionIdentifier(
-        MultibindingContributionIdentifier identifier);
-
-    @CheckReturnValue
-    public abstract Key build();
-  }
-
-  /**
-   * An object that identifies a multibinding contribution method and the module class that
-   * contributes it to the graph.
-   *
-   * @see #multibindingContributionIdentifier()
-   */
-  public static final class MultibindingContributionIdentifier {
-    private final String module;
-    private final String bindingElement;
-
-    /**
-     * @deprecated This is only meant to be called from code in {@code dagger.internal.codegen}.
-     * It is not part of a specified API and may change at any point.
-     */
-    @Deprecated
-    public MultibindingContributionIdentifier(
-        // TODO(ronshapiro): reverse the order of these parameters
-        ExecutableElement bindingMethod, TypeElement contributingModule) {
-      this(
-          bindingMethod.getSimpleName().toString(),
-          contributingModule.getQualifiedName().toString());
-    }
-
-    // TODO(ronshapiro,dpb): create KeyProxies so that these constructors don't need to be public.
-    @Deprecated
-    public MultibindingContributionIdentifier(String bindingElement, String module) {
-      this.module = module;
-      this.bindingElement = bindingElement;
-    }
-
-    /**
-     * @deprecated This is only meant to be called from code in {@code dagger.internal.codegen}.
-     * It is not part of a specified API and may change at any point.
-     */
-    @Deprecated
-    public String module() {
-      return module;
-    }
-
-    /**
-     * @deprecated This is only meant to be called from code in {@code dagger.internal.codegen}.
-     * It is not part of a specified API and may change at any point.
-     */
-    @Deprecated
-    public String bindingElement() {
-      return bindingElement;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>The returned string is human-readable and distinguishes the keys in the same way as the
-     * whole object.
-     */
-    @Override
-    public String toString() {
-      return String.format("%s#%s", module, bindingElement);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof MultibindingContributionIdentifier) {
-        MultibindingContributionIdentifier other = (MultibindingContributionIdentifier) obj;
-        return module.equals(other.module) && bindingElement.equals(other.bindingElement);
-      }
-      return false;
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hash(module, bindingElement);
-    }
-  }
-}
diff --git a/java/dagger/model/RequestKind.java b/java/dagger/model/RequestKind.java
deleted file mode 100644
index 74a4346..0000000
--- a/java/dagger/model/RequestKind.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 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.model;
-
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
-import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
-
-import dagger.Lazy;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import javax.inject.Provider;
-
-/**
- * Represents the different kinds of {@link javax.lang.model.type.TypeMirror types} that may be
- * requested as dependencies for the same key. For example, {@code String}, {@code
- * Provider<String>}, and {@code Lazy<String>} can all be requested if a key exists for {@code
- * String}; they have the {@link #INSTANCE}, {@link #PROVIDER}, and {@link #LAZY} request kinds,
- * respectively.
- */
-public enum RequestKind {
-  /** A default request for an instance. E.g.: {@code FooType} */
-  INSTANCE,
-
-  /** A request for a {@link Provider}. E.g.: {@code Provider<FooType>} */
-  PROVIDER,
-
-  /** A request for a {@link Lazy}. E.g.: {@code Lazy<FooType>} */
-  LAZY,
-
-  /** A request for a {@link Provider} of a {@link Lazy}. E.g.: {@code Provider<Lazy<FooType>>} */
-  PROVIDER_OF_LAZY,
-
-  /**
-   * A request for a members injection. E.g. {@code void injectMembers(FooType);}. Can only be
-   * requested by component interfaces.
-   */
-  MEMBERS_INJECTION,
-
-  /** A request for a {@link Producer}. E.g.: {@code Producer<FooType>} */
-  PRODUCER,
-
-  /** A request for a {@link Produced}. E.g.: {@code Produced<FooType>} */
-  PRODUCED,
-
-  /**
-   * A request for a {@link com.google.common.util.concurrent.ListenableFuture}. E.g.: {@code
-   * ListenableFuture<FooType>}. These can only be requested by component interfaces.
-   */
-  FUTURE,
-  ;
-
-  /** Returns a string that represents requests of this kind for a key. */
-  public String format(Key key) {
-    switch (this) {
-      case INSTANCE:
-        return key.toString();
-
-      case PROVIDER_OF_LAZY:
-        return String.format("Provider<Lazy<%s>>", key);
-
-      case MEMBERS_INJECTION:
-        return String.format("injectMembers(%s)", key);
-
-      case FUTURE:
-        return String.format("ListenableFuture<%s>", key);
-
-      default:
-        return String.format("%s<%s>", UPPER_UNDERSCORE.to(UPPER_CAMEL, name()), key);
-    }
-  }
-}
diff --git a/java/dagger/model/Scope.java b/java/dagger/model/Scope.java
deleted file mode 100644
index f48fa16..0000000
--- a/java/dagger/model/Scope.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2015 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.model;
-
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Equivalence;
-import dagger.Reusable;
-import dagger.producers.ProductionScope;
-import java.lang.annotation.Annotation;
-import javax.inject.Singleton;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.TypeElement;
-
-/** A representation of a {@link javax.inject.Scope}. */
-@AutoValue
-// TODO(ronshapiro): point to SimpleAnnotationMirror
-public abstract class Scope {
-  abstract Equivalence.Wrapper<AnnotationMirror> wrappedScopeAnnotation();
-
-  /** The {@link AnnotationMirror} that represents the scope annotation. */
-  public final AnnotationMirror scopeAnnotation() {
-    return wrappedScopeAnnotation().get();
-  }
-
-  /** The scope annotation element. */
-  public final TypeElement scopeAnnotationElement() {
-    return MoreTypes.asTypeElement(scopeAnnotation().getAnnotationType());
-  }
-
-  /**
-   * Creates a {@link Scope} object from the {@link javax.inject.Scope}-annotated annotation type.
-   */
-  public static Scope scope(AnnotationMirror scopeAnnotation) {
-    checkArgument(isScope(scopeAnnotation));
-    return new AutoValue_Scope(AnnotationMirrors.equivalence().wrap(scopeAnnotation));
-  }
-
-  /**
-   * Returns {@code true} if {@link #scopeAnnotation()} is a {@link javax.inject.Scope} annotation.
-   */
-  public static boolean isScope(AnnotationMirror scopeAnnotation) {
-    return isScope(MoreElements.asType(scopeAnnotation.getAnnotationType().asElement()));
-  }
-
-  /**
-   * Returns {@code true} if {@code scopeAnnotationType} is a {@link javax.inject.Scope} annotation.
-   */
-  public static boolean isScope(TypeElement scopeAnnotationType) {
-    return isAnnotationPresent(scopeAnnotationType, javax.inject.Scope.class);
-  }
-
-  /** Returns {@code true} if this scope is the {@link Singleton @Singleton} scope. */
-  public final boolean isSingleton() {
-    return isScope(Singleton.class);
-  }
-
-  /** Returns {@code true} if this scope is the {@link Reusable @Reusable} scope. */
-  public final boolean isReusable() {
-    return isScope(Reusable.class);
-  }
-
-  /** Returns {@code true} if this scope is the {@link ProductionScope @ProductionScope} scope. */
-  public final boolean isProductionScope() {
-    return isScope(ProductionScope.class);
-  }
-
-  private boolean isScope(Class<? extends Annotation> annotation) {
-    return scopeAnnotationElement().getQualifiedName().contentEquals(annotation.getCanonicalName());
-  }
-
-  /** Returns a debug representation of the scope. */
-  @Override
-  public final String toString() {
-    return scopeAnnotation().toString();
-  }
-}
diff --git a/java/dagger/model/package-info.java b/java/dagger/model/package-info.java
deleted file mode 100644
index 7d09114..0000000
--- a/java/dagger/model/package-info.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-/**
- * This package contains the APIs that are core to Dagger's internal model of bindings and the
- * binding graph. The types are shared with the Dagger processor and are exposed to clients of the
- * Dagger SPI.
- *
- * <p>Unless otherwise specified, the types/interfaces are only intended to be implemented in this
- * package (i.e. via {@code @AutoValue}) or by Dagger's processor. This applies to test code as
- * well, so if you need a fake, please file a feature request instead of implementing it yourself.
- */
-@CheckReturnValue
-@Beta
-package dagger.model;
-
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.internal.Beta;
diff --git a/java/dagger/model/testing/BUILD b/java/dagger/model/testing/BUILD
deleted file mode 100644
index a9d5f19..0000000
--- a/java/dagger/model/testing/BUILD
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018 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.
-
-# Description:
-#   Test utilities for the Dagger model
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-
-java_library(
-    name = "testing",
-    testonly = 1,
-    srcs = glob(["*.java"]),
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = [
-        "//java/dagger/internal/codegen:jdk-and-guava-extras",
-        "//java/dagger/model",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/checker_framework_annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/java/dagger/model/testing/BindingGraphSubject.java b/java/dagger/model/testing/BindingGraphSubject.java
deleted file mode 100644
index dc17c1d..0000000
--- a/java/dagger/model/testing/BindingGraphSubject.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2018 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.model.testing;
-
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.common.truth.Truth.assertAbout;
-import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-import dagger.model.Binding;
-import dagger.model.BindingGraph;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/** A Truth subject for making assertions on a {@link BindingGraph}. */
-public final class BindingGraphSubject extends Subject<BindingGraphSubject, BindingGraph> {
-
-  /** Starts a fluent assertion about a {@link BindingGraph}. */
-  public static BindingGraphSubject assertThat(BindingGraph bindingGraph) {
-    return assertAbout(BindingGraphSubject::new).that(bindingGraph);
-  }
-
-  private final BindingGraph actual;
-
-  private BindingGraphSubject(FailureMetadata metadata, @NullableDecl BindingGraph actual) {
-    super(metadata, actual);
-    this.actual = actual;
-  }
-
-  /**
-   * Asserts that the graph has at least one binding with an unqualified key.
-   *
-   * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-   */
-  public void hasBindingWithKey(String type) {
-    bindingWithKey(type);
-  }
-
-  /**
-   * Asserts that the graph has at least one binding with a qualified key.
-   *
-   * @param qualifier the canonical string form of the qualifier, as returned by {@link
-   *     javax.lang.model.element.AnnotationMirror AnnotationMirror.toString()}
-   * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-   */
-  public void hasBindingWithKey(String qualifier, String type) {
-    bindingWithKey(qualifier, type);
-  }
-
-  /**
-   * Returns a subject for testing the binding for an unqualified key.
-   *
-   * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-   */
-  public BindingSubject bindingWithKey(String type) {
-    return bindingWithKeyString(keyString(type));
-  }
-
-  /**
-   * Returns a subject for testing the binding for a qualified key.
-   *
-   * @param qualifier the canonical string form of the qualifier, as returned by {@link
-   *     javax.lang.model.element.AnnotationMirror AnnotationMirror.toString()}
-   * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-   */
-  public BindingSubject bindingWithKey(String qualifier, String type) {
-    return bindingWithKeyString(keyString(qualifier, type));
-  }
-
-  private BindingSubject bindingWithKeyString(String keyString) {
-    ImmutableSet<Binding> bindings = getBindingNodes(keyString);
-    // TODO(dpb): Handle multiple bindings for the same key.
-    check("bindingsWithKey(%s)", keyString).that(bindings).hasSize(1);
-    return check("bindingWithKey(%s)", keyString)
-        .about(BindingSubject::new)
-        .that(getOnlyElement(bindings));
-  }
-
-  private ImmutableSet<Binding> getBindingNodes(String keyString) {
-    return actual.bindings().stream()
-        .filter(binding -> binding.key().toString().equals(keyString))
-        .collect(toImmutableSet());
-  }
-
-  private static String keyString(String type) {
-    return type;
-  }
-
-  private static String keyString(String qualifier, String type) {
-    return String.format("%s %s", qualifier, type);
-  }
-
-  /** A Truth subject for a {@link Binding}. */
-  public final class BindingSubject extends Subject<BindingSubject, Binding> {
-
-    private final Binding actual;
-
-    BindingSubject(FailureMetadata metadata, @NullableDecl Binding actual) {
-      super(metadata, actual);
-      this.actual = actual;
-    }
-
-    /**
-     * Asserts that the binding depends on a binding with an unqualified key.
-     *
-     * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-     */
-    public void dependsOnBindingWithKey(String type) {
-      dependsOnBindingWithKeyString(keyString(type));
-    }
-
-    /**
-     * Asserts that the binding depends on a binding with a qualified key.
-     *
-     * @param qualifier the canonical string form of the qualifier, as returned by {@link
-     *     javax.lang.model.element.AnnotationMirror AnnotationMirror.toString()}
-     * @param type the canonical name of the type, as returned by {@link TypeMirror#toString()}
-     */
-    public void dependsOnBindingWithKey(String qualifier, String type) {
-      dependsOnBindingWithKeyString(keyString(qualifier, type));
-    }
-
-    private void dependsOnBindingWithKeyString(String keyString) {
-      if (actualBindingGraph().requestedBindings(actual).stream()
-          .noneMatch(binding -> binding.key().toString().equals(keyString))) {
-        failWithActual("expected to depend on binding with key", keyString);
-      }
-    }
-
-    private BindingGraph actualBindingGraph() {
-      return BindingGraphSubject.this.actual;
-    }
-  }
-}
diff --git a/java/dagger/multibindings/ClassKey.java b/java/dagger/multibindings/ClassKey.java
deleted file mode 100644
index ac25545..0000000
--- a/java/dagger/multibindings/ClassKey.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.MapKey;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * A {@link MapKey} annotation for maps with {@code Class<?>} keys.
- *
- * <p>If your map's keys can be constrained, consider using a custom annotation instead, with a
- * member whose type is {@code Class<? extends Something>}.
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-@MapKey
-public @interface ClassKey {
-  Class<?> value();
-}
diff --git a/java/dagger/multibindings/ElementsIntoSet.java b/java/dagger/multibindings/ElementsIntoSet.java
deleted file mode 100644
index 5ed68c6..0000000
--- a/java/dagger/multibindings/ElementsIntoSet.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * The method's return type is {@code Set<T>} and all values are contributed to the set. The {@code
- * Set<T>} produced from the accumulation of values will be immutable. An example use is to provide
- * a default empty set binding, which is otherwise not possible using {@link IntoSet}.
- *
- * @see <a href="https://dagger.dev/multibindings#set-multibindings">Set multibinding</a>
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-public @interface ElementsIntoSet {}
diff --git a/java/dagger/multibindings/IntKey.java b/java/dagger/multibindings/IntKey.java
deleted file mode 100644
index 55e79a1..0000000
--- a/java/dagger/multibindings/IntKey.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.MapKey;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/** A {@link MapKey} annotation for maps with {@code int} keys. */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-@MapKey
-public @interface IntKey {
-  int value();
-}
diff --git a/java/dagger/multibindings/IntoMap.java b/java/dagger/multibindings/IntoMap.java
deleted file mode 100644
index d760229..0000000
--- a/java/dagger/multibindings/IntoMap.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * The method's return type forms the type argument for the value of a {@code Map<K, Provider<V>>},
- * and the combination of the annotated key and the returned value is contributed to the map as a
- * key/value pair. The {@code Map<K, Provider<V>>} produced from the accumulation of values will be
- * immutable.
- *
- * @see <a href="https://dagger.dev/multibindings#map-multibindings">Map multibinding</a>
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-public @interface IntoMap {}
diff --git a/java/dagger/multibindings/IntoSet.java b/java/dagger/multibindings/IntoSet.java
deleted file mode 100644
index b4fdcc4..0000000
--- a/java/dagger/multibindings/IntoSet.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * The method's return type forms the generic type argument of a {@code Set<T>}, and the returned
- * value is contributed to the set. The object graph will pass dependencies to the method as
- * parameters. The {@code Set<T>} produced from the accumulation of values will be immutable.
- *
- * @see <a href="https://dagger.dev/multibindings#set-multibindings">Set multibinding</a>
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-public @interface IntoSet {}
diff --git a/java/dagger/multibindings/LongKey.java b/java/dagger/multibindings/LongKey.java
deleted file mode 100644
index 71d0fe1..0000000
--- a/java/dagger/multibindings/LongKey.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.MapKey;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/** A {@link MapKey} annotation for maps with {@code long} keys. */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-@MapKey
-public @interface LongKey {
-  long value();
-}
diff --git a/java/dagger/multibindings/Multibinds.java b/java/dagger/multibindings/Multibinds.java
deleted file mode 100644
index e37b39e..0000000
--- a/java/dagger/multibindings/Multibinds.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates abstract module methods that declare multibindings.
- *
- * <p>You can declare that a multibound set or map is bound by annotating an abstract module method
- * that returns the set or map you want to declare with {@code @Multibinds}.
- *
- * <p>You do not have to use {@code @Multibinds} for sets or maps that have at least one
- * contribution, but you do have to declare them if they may be empty.
- *
- * <pre><code>
- *   {@literal @Module} abstract class MyModule {
- *     {@literal @Multibinds abstract Set<Foo> aSet();}
- *     {@literal @Multibinds abstract @MyQualifier Set<Foo> aQualifiedSet();}
- *     {@literal @Multibinds abstract Map<String, Foo> aMap();}
- *     {@literal @Multibinds abstract @MyQualifier Map<String, Foo> aQualifiedMap();}
- *
- *     {@literal @Provides}
- *     {@literal static Object usesMultibindings(Set<Foo> set, @MyQualifier Map<String, Foo> map}) {
- *       return …
- *     }
- *   }</code></pre>
- *
- * <p>A given set or map multibinding can be declared any number of times without error. Dagger
- * never implements or calls any {@code @Multibinds} methods.
- *
- * @see <a href="https://dagger.dev/multibindings">Multibindings</a>
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-public @interface Multibinds {}
diff --git a/java/dagger/multibindings/StringKey.java b/java/dagger/multibindings/StringKey.java
deleted file mode 100644
index 5dad8e3..0000000
--- a/java/dagger/multibindings/StringKey.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.multibindings;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.MapKey;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/** A {@link MapKey} annotation for maps with {@link String} keys. */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-@MapKey
-public @interface StringKey {
-  String value();
-}
diff --git a/java/dagger/multibindings/package-info.java b/java/dagger/multibindings/package-info.java
deleted file mode 100644
index d6fe1e1..0000000
--- a/java/dagger/multibindings/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-/**
- * This package contains the API by which Dagger allows you to bind several objects into a
- * collection that can be injected without depending directly on each of the individual bindings.
- *
- * @see <a href="https://dagger.dev/multibindings">Multibindings in the Dagger User's Guide</a>
- */
-package dagger.multibindings;
diff --git a/java/dagger/package-info.java b/java/dagger/package-info.java
deleted file mode 100644
index b680a85..0000000
--- a/java/dagger/package-info.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-/**
- * This package contains the public API for the <a href="https://dagger.dev/">Dagger 2</a> dependency
- * injection framework. By building upon <a href="https://jcp.org/en/jsr/detail?id=330">JSR 330</a>,
- * Dagger 2 provides an annotation-driven API for dependency injection whose implementation is
- * entirely generated at compile time by <a
- * href="http://en.wikipedia.org/wiki/Java_annotation#Processing">annotation processors</a>.
- *
- * <p>The entry point into the API is the {@link Component}, which annotates abstract types for
- * Dagger 2 to implement. The dependency graph is configured using annotations such as {@link
- * Module}, {@link Provides} and {@link javax.inject.Inject}.
- *
- * <p>{@code dagger.internal.codegen.ComponentProcessor} is the processor responsible for generating
- * the implementation. Dagger uses the annotation procesor {@linkplain java.util.ServiceLoader
- * service loader} to automatically configure the processor, so explict build configuration
- * shouldn't be necessary.
- */
-package dagger;
diff --git a/java/dagger/producers/BUILD b/java/dagger/producers/BUILD
deleted file mode 100644
index ad065a1..0000000
--- a/java/dagger/producers/BUILD
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   An asynchronous dependency injection system that extends JSR-330.
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-    "SOURCE_7_TARGET_7",
-)
-load("//tools:maven.bzl", "pom_file", "POM_VERSION")
-
-# Work around b/70476182 which prevents Kythe from connecting :producers to the .java files it
-# contains.
-SRCS = glob(["**/*.java"])
-
-filegroup(
-    name = "producers-srcs",
-    srcs = SRCS,
-)
-
-java_library(
-    name = "producers",
-    srcs = SRCS,
-    javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    tags = ["maven_coordinates=com.google.dagger:dagger-producers:" + POM_VERSION],
-    exports = [
-        # TODO(dpb): Don't export any of Guava.
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-    deps = [
-        "//java/dagger:core",
-        "@google_bazel_common//third_party/java/checker_framework_annotations",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-producers",
-    artifact_name = "Dagger Producers",
-    targets = [":producers"],
-)
-
-load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library")
-
-javadoc_library(
-    name = "producers-javadoc",
-    srcs = SRCS,
-    exclude_packages = [
-        "dagger.producers.internal",
-        "dagger.producers.monitoring.internal",
-    ],
-    root_packages = ["dagger.producers"],
-    deps = [":producers"],
-)
diff --git a/java/dagger/producers/CancellationPolicy.java b/java/dagger/producers/CancellationPolicy.java
deleted file mode 100644
index 70f4a43..0000000
--- a/java/dagger/producers/CancellationPolicy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates a production component or subcomponent to specify its policy when a child component is
- * cancelled.
- *
- * <p>When a future returned from an entry point on a production component is cancelled, the
- * component is cancelled: all producers in the component (including those for other entry points)
- * are cancelled.
- *
- * <p>When a child component is cancelled, its parent component <i>is not</i> cancelled unless the
- * parent component is annotated with {@code @CancellationPolicy(fromSubcomponents = PROPAGATE)}. If
- * that parent component has a parent (the grandparent of the cancelled child component), it will
- * not be cancelled unless it also has a {@code @CancellationPolicy} annotation allowing
- * cancellation to propagate to it from subcomponents.
- */
-@Documented
-@Target(TYPE)
-@Retention(CLASS)
-@Beta
-public @interface CancellationPolicy {
-  /**
-   * Defines whether the annotated production component is cancelled when a child component is
-   * cancelled.
-   *
-   * <p>The default, if no cancellation policy annotation is provided, is {@link
-   * Propagation#IGNORE}.
-   */
-  Propagation fromSubcomponents();
-
-  /**
-   * Enumeration of the options for what happens to a parent component when one of its child
-   * components is cancelled.
-   */
-  enum Propagation {
-    /** Cancel the annotated component when a child component is cancelled. */
-    PROPAGATE,
-
-    /** Do not cancel the annotated component when a child component is cancelled. */
-    IGNORE
-  }
-}
diff --git a/java/dagger/producers/Produced.java b/java/dagger/producers/Produced.java
deleted file mode 100644
index 5b7847f..0000000
--- a/java/dagger/producers/Produced.java
+++ /dev/null
@@ -1,153 +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.producers;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Objects;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.internal.Beta;
-import java.util.concurrent.ExecutionException;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/**
- * An interface that represents the result of a {@linkplain Producer production} of type {@code T},
- * or an exception that was thrown during that production. For any type {@code T} that can be
- * injected, you can also inject {@code Produced<T>}, which enables handling of any exceptions that
- * were thrown during the production of {@code T}.
- *
- * <p>For example: <pre><code>
- *   {@literal @}Produces Html getResponse(
- *       UserInfo criticalInfo, {@literal Produced<ExtraInfo>} noncriticalInfo) {
- *     try {
- *       return new Html(criticalInfo, noncriticalInfo.get());
- *     } catch (ExecutionException e) {
- *       logger.warning(e, "Noncritical info");
- *       return new Html(criticalInfo);
- *     }
- *   }
- * </code></pre>
- *
- * @since 2.0
- */
-@Beta
-@CheckReturnValue
-public abstract class Produced<T> {
-  /**
-   * Returns the result of a production.
-   *
-   * @throws ExecutionException if the production threw an exception
-   */
-  public abstract T get() throws ExecutionException;
-
-  /**
-   * Two {@code Produced} objects compare equal if both are successful with equal values, or both
-   * are failed with equal exceptions.
-   */
-  @Override
-  public abstract boolean equals(Object o);
-
-  /** Returns an appropriate hash code to match {@link #equals(Object)}. */
-  @Override
-  public abstract int hashCode();
-
-  /** Returns a successful {@code Produced}, whose {@link #get} will return the given value. */
-  public static <T> Produced<T> successful(@NullableDecl T value) {
-    return new Successful<T>(value);
-  }
-
-  /**
-   * Returns a failed {@code Produced}, whose {@link #get} will throw an
-   * {@code ExecutionException} with the given cause.
-   */
-  public static <T> Produced<T> failed(Throwable throwable) {
-    return new Failed<T>(checkNotNull(throwable));
-  }
-
-  private static final class Successful<T> extends Produced<T> {
-    @NullableDecl private final T value;
-
-    private Successful(@NullableDecl T value) {
-      this.value = value;
-    }
-
-    @Override
-    @NullableDecl
-    public T get() {
-      return value;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (o == this) {
-        return true;
-      } else if (o instanceof Successful) {
-        Successful<?> that = (Successful<?>) o;
-        return Objects.equal(this.value, that.value);
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public int hashCode() {
-      return value == null ? 0 : value.hashCode();
-    }
-
-    @Override
-    public String toString() {
-      return "Produced[" + value + "]";
-    }
-  }
-
-  private static final class Failed<T> extends Produced<T> {
-    private final Throwable throwable;
-
-    private Failed(Throwable throwable) {
-      this.throwable = checkNotNull(throwable);
-    }
-
-    @Override
-    public T get() throws ExecutionException {
-      throw new ExecutionException(throwable);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (o == this) {
-        return true;
-      } else if (o instanceof Failed) {
-        Failed<?> that = (Failed<?>) o;
-        return this.throwable.equals(that.throwable);
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public int hashCode() {
-      return throwable.hashCode();
-    }
-
-    @Override
-    public String toString() {
-      return "Produced[failed with " + throwable.getClass().getCanonicalName() + "]";
-    }
-  }
-
-  private Produced() {}
-}
diff --git a/java/dagger/producers/Producer.java b/java/dagger/producers/Producer.java
deleted file mode 100644
index 8485f81..0000000
--- a/java/dagger/producers/Producer.java
+++ /dev/null
@@ -1,107 +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.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.internal.Beta;
-
-/**
- * An interface that represents the production of a type {@code T}. You can also inject
- * {@code Producer<T>} instead of {@code T}, which will delay the execution of any code that
- * produces the {@code T} until {@link #get} is called.
- *
- * <p>For example, you might inject {@code Producer} to lazily choose between several different
- * implementations of some type: <pre><code>
- *   {@literal @Produces ListenableFuture<Heater>} getHeater(
- *       HeaterFlag flag,
- *       {@literal @Electric Producer<Heater>} electricHeater,
- *       {@literal @Gas Producer<Heater>} gasHeater) {
- *     return flag.useElectricHeater() ? electricHeater.get() : gasHeater.get();
- *   }
- * </code></pre>
- *
- * <p>Here is a complete example that demonstrates how calling {@code get()} will cause each
- * method to be executed: <pre><code>
- *
- *   {@literal @}ProducerModule
- *   final class MyModule {
- *     {@literal @Produces ListenableFuture<A>} a() {
- *       System.out.println("a");
- *       return Futures.immediateFuture(new A());
- *     }
- *
- *     {@literal @Produces ListenableFuture<B>} b(A a) {
- *       System.out.println("b");
- *       return Futures.immediateFuture(new B(a));
- *     }
- *
- *     {@literal @Produces ListenableFuture<C>} c(B b) {
- *       System.out.println("c");
- *       return Futures.immediateFuture(new C(b));
- *     }
- *
- *     {@literal @Produces @Delayed ListenableFuture<C>} delayedC(A a, {@literal Producer<C>} c) {
- *       System.out.println("delayed c");
- *       return c.get();
- *     }
- *   }
- *
- *   {@literal @}ProductionComponent(modules = MyModule.class)
- *   interface MyComponent {
- *     {@literal @Delayed ListenableFuture<C>} delayedC();
- *   }
- * </code></pre>
- * Suppose we instantiate the generated implementation of this component and call
- * {@code delayedC()}: <pre><code>
- *   MyComponent component = DaggerMyComponent
- *       .builder()
- *       .executor(MoreExecutors.directExecutor())
- *       .build();
- *   System.out.println("Constructed component");
- *   {@literal ListenableFuture<C>} cFuture = component.delayedC();
- *   System.out.println("Retrieved future");
- *   C c = cFuture.get();
- *   System.out.println("Retrieved c");
- * </code></pre>
- * Here, we're using {@code MoreExecutors.directExecutor} in order to illustrate how each call
- * directly causes code to execute. The above code will print: <pre><code>
- *   Constructed component
- *   a
- *   delayed c
- *   b
- *   c
- *   Retrieved future
- *   Retrieved c
- * </code></pre>
- *
- * @since 2.0
- */
-@Beta
-public interface Producer<T> {
-  /**
-   * Returns a future representing a running task that produces a value. Calling this method will
-   * trigger the submission of this task to the executor, if it has not already been triggered. In
-   * order to trigger this task's submission, the transitive dependencies required to produce the
-   * {@code T} will be submitted to the executor, as their dependencies become available.
-   *
-   * <p>If the key is bound to a {@link Produces} method, then calling this method multiple times
-   * will return the same future.
-   */
-  @CheckReturnValue
-  ListenableFuture<T> get();
-}
diff --git a/java/dagger/producers/ProducerModule.java b/java/dagger/producers/ProducerModule.java
deleted file mode 100644
index e14d450..0000000
--- a/java/dagger/producers/ProducerModule.java
+++ /dev/null
@@ -1,53 +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.producers;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.Module;
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates a class that contributes {@link Produces} bindings to the production component.
- *
- * @since 2.0
- */
-@Documented
-@Target(TYPE)
-@Retention(RUNTIME)
-@Beta
-public @interface ProducerModule {
-  /**
-   * Additional {@code @ProducerModule}- or {@link Module}-annotated classes from which this module
-   * is composed. The de-duplicated contributions of the modules in {@code includes}, and of their
-   * inclusions recursively, are all contributed to the object graph.
-   */
-  Class<?>[] includes() default {};
-
-  /**
-   * Any {@link dagger.Subcomponent}- or {@link ProductionSubcomponent}-annotated classes which
-   * should be children of the component in which this module is installed. A subcomponent may be
-   * listed in more than one module in a component.
-   *
-   * @since 2.7
-   */
-  Class<?>[] subcomponents() default {};
-}
diff --git a/java/dagger/producers/Producers.java b/java/dagger/producers/Producers.java
deleted file mode 100644
index 1c8da03..0000000
--- a/java/dagger/producers/Producers.java
+++ /dev/null
@@ -1,66 +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.producers;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.internal.Beta;
-import dagger.producers.internal.CancellableProducer;
-import dagger.producers.internal.CancellationListener;
-
-/** Utility methods to create {@link Producer}s. */
-@Beta
-public final class Producers {
-  /** Returns a producer that succeeds with the given value. */
-  public static <T> Producer<T> immediateProducer(final T value) {
-    return new ImmediateProducer<>(Futures.immediateFuture(value));
-  }
-
-  /** Returns a producer that fails with the given exception. */
-  public static <T> Producer<T> immediateFailedProducer(final Throwable throwable) {
-    return new ImmediateProducer<>(Futures.<T>immediateFailedFuture(throwable));
-  }
-
-  /** A {@link CancellableProducer} with an immediate result. */
-  private static final class ImmediateProducer<T> implements CancellableProducer<T> {
-    private final ListenableFuture<T> future;
-
-    ImmediateProducer(ListenableFuture<T> future) {
-      this.future = future;
-    }
-
-    @Override
-    public ListenableFuture<T> get() {
-      return future;
-    }
-
-    @Override
-    public void cancel(boolean mayInterruptIfRunning) {}
-
-    @Override
-    public Producer<T> newDependencyView() {
-      return this;
-    }
-
-    @Override
-    public Producer<T> newEntryPointView(CancellationListener cancellationListener) {
-      return this;
-    }
-  }
-
-  private Producers() {}
-}
diff --git a/java/dagger/producers/Produces.java b/java/dagger/producers/Produces.java
deleted file mode 100644
index df859ad..0000000
--- a/java/dagger/producers/Produces.java
+++ /dev/null
@@ -1,40 +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.producers;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Annotates methods of a producer module to create a production binding. If the method returns a
- * {@link com.google.common.util.concurrent.ListenableFuture} or {@link
- * com.google.common.util.concurrent.FluentFuture}, then the parameter type of the future is bound
- * to the value that the future produces; otherwise, the return type is bound to the returned value.
- * The production component will pass dependencies to the method as parameters.
- *
- * @since 2.0
- */
-@Documented
-@Target(METHOD)
-@Retention(RUNTIME)
-@Beta
-public @interface Produces {}
diff --git a/java/dagger/producers/Production.java b/java/dagger/producers/Production.java
deleted file mode 100644
index 563fc16..0000000
--- a/java/dagger/producers/Production.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * Qualifies a type that will be provided to the framework for use internally.
- *
- * <p>The only type that may be so qualified is {@link java.util.concurrent.Executor}. In this case,
- * the resulting executor is used to schedule {@linkplain Produces producer methods} in a
- * {@link ProductionComponent} or {@link ProductionSubcomponent}.
- */
-@Documented
-@Retention(RUNTIME)
-@Qualifier
-@Beta
-public @interface Production {}
diff --git a/java/dagger/producers/ProductionComponent.java b/java/dagger/producers/ProductionComponent.java
deleted file mode 100644
index a0337cf..0000000
--- a/java/dagger/producers/ProductionComponent.java
+++ /dev/null
@@ -1,121 +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.producers;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-
-/**
- * Annotates an interface or abstract class for which a fully-formed, dependency-injected
- * implementation is to be generated from a set of {@linkplain #modules modules}. The generated
- * class will have the name of the type annotated with {@code @ProductionComponent} prepended with
- * {@code Dagger}. For example, {@code @ProductionComponent interface MyComponent {...}} will
- * produce an implementation named {@code DaggerMyComponent}.
- *
- * <p>Each {@link Produces} method that contributes to the component will be called at most once per
- * component instance, no matter how many times that binding is used as a dependency. TODO(beder):
- * Decide on how scope works for producers.
- *
- * <h2>Component methods</h2>
- *
- * <p>Every type annotated with {@code @ProductionComponent} must contain at least one abstract
- * component method. Component methods must represent {@linkplain Producer production}.
- *
- * <p>Production methods have no arguments and return either a {@link ListenableFuture} or {@link
- * Producer} of a type that is {@link Inject injected}, {@link Provides provided}, or {@link
- * Produces produced}. Each may have a {@link Qualifier} annotation as well. The following are all
- * valid production method declarations:
- *
- * <pre><code>
- *   {@literal ListenableFuture<SomeType>} getSomeType();
- *   {@literal Producer<Set<SomeType>>} getSomeTypes();
- *   {@literal @Response ListenableFuture<Html>} getResponse();
- * </code></pre>
- *
- * <h2>Exceptions</h2>
- *
- * <p>When a producer throws an exception, the exception will be propagated to its downstream
- * producers in the following way: if the downstream producer injects a type {@code T}, then that
- * downstream producer will be skipped, and the exception propagated to its downstream producers;
- * and if the downstream producer injects a {@code Produced<T>}, then the downstream producer will
- * be run with the exception stored in the {@code Produced<T>}.
- *
- * <p>If a non-execution exception is thrown (e.g., an {@code InterruptedException} or {@code
- * CancellationException}), then exception is handled as in {@link
- * com.google.common.util.concurrent.Futures#transform}.
- * <!-- TODO(beder): Explain this more thoroughly, and update the javadocs of those utilities. -->
- *
- * <h2>Executor</h2>
- *
- * <p>The component must include a binding for <code>{@literal @}{@link Production}
- * {@link java.util.concurrent.Executor}</code>; this binding will be called exactly once, and the
- * provided executor will be used by the framework to schedule all producer methods (for this
- * component, and any {@link ProductionSubcomponent} it may have.
- *
- * @since 2.0
- */
-@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-@Documented
-@Target(TYPE)
-@Beta
-public @interface ProductionComponent {
-  /**
-   * A list of classes annotated with {@link Module} or {@link ProducerModule} whose bindings are
-   * used to generate the component implementation.
-   */
-  Class<?>[] modules() default {};
-
-  /**
-   * A list of types that are to be used as component dependencies.
-   */
-  Class<?>[] dependencies() default {};
-
-  /**
-   * A builder for a production component.
-   *
-   * <p>This follows all the rules of {@link Component.Builder}, except it must appear in classes
-   * annotated with {@link ProductionComponent} instead of {@code Component}.
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Builder {}
-
-  /**
-   * A factory for a production component.
-   *
-   * <p>This follows all the rules of {@link Component.Factory}, except it must appear in classes
-   * annotated with {@link ProductionComponent} instead of {@code Component}.
-   *
-   * @since 2.22
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Factory {}
-}
diff --git a/java/dagger/producers/ProductionScope.java b/java/dagger/producers/ProductionScope.java
deleted file mode 100644
index 393c240..0000000
--- a/java/dagger/producers/ProductionScope.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-/**
- * A scope annotation for provision bindings that are tied to the lifetime of a
- * {@link ProductionComponent} or {@link ProductionSubcomponent}.
- */
-@Documented
-@Retention(RUNTIME)
-@Scope
-public @interface ProductionScope {}
diff --git a/java/dagger/producers/ProductionSubcomponent.java b/java/dagger/producers/ProductionSubcomponent.java
deleted file mode 100644
index 5774945..0000000
--- a/java/dagger/producers/ProductionSubcomponent.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Subcomponent;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * A subcomponent that inherits the bindings from a parent {@link Component}, {@link Subcomponent},
- * {@link ProductionComponent}, or {@link ProductionSubcomponent}. The details of how to associate a
- * subcomponent with a parent are described in the documentation for {@link Component}.
- *
- * <p>The executor for a production subcomponent is supplied by binding
- * <code>{@literal @}Production Executor</code>, similar to {@link ProductionComponent}. Note that
- * this binding may be in an ancestor component.
- *
- * @since 2.1
- */
-@Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-@Target(TYPE)
-@Documented
-public @interface ProductionSubcomponent {
-  /**
-   * A list of classes annotated with {@link Module} or {@link ProducerModule} whose bindings are
-   * used to generate the subcomponent implementation.  Note that through the use of
-   * {@link Module#includes} or {@link ProducerModule#includes} the full set of modules used to
-   * implement the subcomponent may include more modules that just those listed here.
-   */
-  Class<?>[] modules() default {};
-
-  /**
-   * A builder for a production subcomponent.
-   *
-   * <p>This follows all the rules of {@link Component.Builder}, except it must appear in classes
-   * annotated with {@link ProductionSubcomponent} instead of {@code Component}.
-   *
-   * <p>If a subcomponent defines a builder, its parent component(s) will have a binding for that
-   * builder type, allowing an instance or {@code Provider} of that builder to be injected or
-   * returned from a method on that component like any other binding.
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Builder {}
-
-  /**
-   * A factory for a production subcomponent.
-   *
-   * <p>This follows all the rules of {@link Component.Factory}, except it must appear in classes
-   * annotated with {@link ProductionSubcomponent} instead of {@code Component}.
-   *
-   * <p>If a subcomponent defines a factory, its parent component(s) will have a binding for that
-   * factory type, allowing an instance that factory to be injected or returned from a method on
-   * that component like any other binding.
-   *
-   * @since 2.22
-   */
-  @Retention(RUNTIME) // Allows runtimes to have specialized behavior interoperating with Dagger.
-  @Target(TYPE)
-  @Documented
-  @interface Factory {}
-}
diff --git a/java/dagger/producers/internal/AbstractMapProducer.java b/java/dagger/producers/internal/AbstractMapProducer.java
deleted file mode 100644
index c60f0cb..0000000
--- a/java/dagger/producers/internal/AbstractMapProducer.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static dagger.producers.internal.Producers.producerFromProvider;
-
-import com.google.common.collect.ImmutableMap;
-import dagger.producers.Producer;
-import java.util.Map;
-import javax.inject.Provider;
-
-/**
- * An {@code abstract} {@link Producer} implementation used to implement {@link Map} bindings.
- *
- * @param <K>The key type of the map that this produces
- * @param <V>The type that each contributing producer
- * @param <V2>The value type of the map that this produces. For {@link MapProducer}, {@code V} and
- *     {@code V2} will be equivalent.
- */
-abstract class AbstractMapProducer<K, V, V2> extends AbstractProducer<Map<K, V2>> {
-  private final ImmutableMap<K, Producer<V>> contributingMap;
-
-  AbstractMapProducer(ImmutableMap<K, Producer<V>> contributingMap) {
-    this.contributingMap = contributingMap;
-  }
-
-  /** The map of {@link Producer}s that contribute to this map binding. */
-  final ImmutableMap<K, Producer<V>> contributingMap() {
-    return contributingMap;
-  }
-
-  /** A builder for {@link AbstractMapProducer} */
-  public abstract static class Builder<K, V, V2> {
-    final ImmutableMap.Builder<K, Producer<V>> mapBuilder;
-
-    Builder(int size) {
-      mapBuilder = ImmutableMap.builderWithExpectedSize(size);
-    }
-
-    // Unfortunately, we cannot return a self-type here because a raw Producer type passed to one of
-    // these methods affects the returned type of the method. The first put*() call erases the self
-    // type to the "raw" self type, and the second erases the type to the upper bound
-    // (AbstractMapProducer.Builder), which doesn't have a build() method.
-    //
-    // The methods are therefore not declared public so that each subtype will redeclare them and
-    // expand their accessibility
-
-    /** Associates {@code key} with {@code producerOfValue}. */
-    Builder<K, V, V2> put(K key, Producer<V> producerOfValue) {
-      checkNotNull(key, "key");
-      checkNotNull(producerOfValue, "producer of value");
-      mapBuilder.put(key, producerOfValue);
-      return this;
-    }
-
-    /** Associates {@code key} with {@code providerOfValue}. */
-    Builder<K, V, V2> put(K key, Provider<V> providerOfValue) {
-      checkNotNull(key, "key");
-      checkNotNull(providerOfValue, "provider of value");
-      mapBuilder.put(key, producerFromProvider(providerOfValue));
-      return this;
-    }
-
-    /** Adds contributions from a super-implementation of a component into this builder. */
-    Builder<K, V, V2> putAll(Producer<Map<K, V2>> mapOfProducers) {
-      if (mapOfProducers instanceof DelegateProducer) {
-        @SuppressWarnings("unchecked")
-        DelegateProducer<Map<K, V2>> asDelegateProducer = (DelegateProducer) mapOfProducers;
-        return putAll(asDelegateProducer.getDelegate());
-      }
-      @SuppressWarnings("unchecked")
-      AbstractMapProducer<K, V, ?> asAbstractMapProducer =
-          ((AbstractMapProducer<K, V, ?>) (Producer) mapOfProducers);
-      mapBuilder.putAll(asAbstractMapProducer.contributingMap);
-      return this;
-    }
-  }
-}
diff --git a/java/dagger/producers/internal/AbstractProducer.java b/java/dagger/producers/internal/AbstractProducer.java
deleted file mode 100644
index 3dcd906..0000000
--- a/java/dagger/producers/internal/AbstractProducer.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.internal;
-
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/** An abstract {@link Producer} implementation that memoizes the result of its compute method. */
-public abstract class AbstractProducer<T> implements CancellableProducer<T> {
-  private final AtomicBoolean requested = new AtomicBoolean();
-  private final NonExternallyCancellableFuture<T> future = new NonExternallyCancellableFuture<T>();
-
-  protected AbstractProducer() {}
-
-  /** Computes this producer's future, which is then cached in {@link #get}. */
-  protected abstract ListenableFuture<T> compute();
-
-  @Override
-  public final ListenableFuture<T> get() {
-    if (requested.compareAndSet(false, true)) {
-      future.setFuture(compute());
-    }
-    return future;
-  }
-
-  @Override
-  public final void cancel(boolean mayInterruptIfRunning) {
-    requested.set(true); // Avoid potentially starting the task later only to cancel it immediately.
-    future.doCancel(mayInterruptIfRunning);
-  }
-
-  @Override
-  public Producer<T> newDependencyView() {
-    return new NonCancellationPropagatingView();
-  }
-
-  @Override
-  public Producer<T> newEntryPointView(CancellationListener cancellationListener) {
-    NonCancellationPropagatingView result = new NonCancellationPropagatingView();
-    result.addCancellationListener(cancellationListener);
-    return result;
-  }
-
-  /**
-   * A view of this producer that returns a future that can be cancelled without cancelling the
-   * producer itself.
-   */
-  private final class NonCancellationPropagatingView implements Producer<T> {
-    /**
-     * An independently cancellable view of this node. Needs to be cancellable by normal future
-     * cancellation so that the view at an entry point can listen for its cancellation.
-     */
-    private final ListenableFuture<T> viewFuture = nonCancellationPropagating(future);
-
-    @SuppressWarnings("FutureReturnValueIgnored")
-    @Override
-    public ListenableFuture<T> get() {
-      AbstractProducer.this.get(); // force compute()
-      return viewFuture;
-    }
-
-    void addCancellationListener(final CancellationListener cancellationListener) {
-      viewFuture.addListener(
-          new Runnable() {
-            @Override
-            public void run() {
-              if (viewFuture.isCancelled()) {
-                boolean mayInterruptIfRunning =
-                    viewFuture instanceof NonCancellationPropagatingFuture
-                        && ((NonCancellationPropagatingFuture) viewFuture).interrupted();
-                cancellationListener.onProducerFutureCancelled(mayInterruptIfRunning);
-              }
-            }
-          },
-          directExecutor());
-    }
-  }
-
-  /** A settable future that can't be cancelled via normal future cancellation. */
-  private static final class NonExternallyCancellableFuture<T> extends AbstractFuture<T> {
-
-    @Override
-    public boolean setFuture(ListenableFuture<? extends T> future) {
-      return super.setFuture(future);
-    }
-
-    @Override
-    public boolean cancel(boolean mayInterruptIfRunning) {
-      return false;
-    }
-
-    /** Actually cancels this future. */
-    void doCancel(boolean mayInterruptIfRunning) {
-      super.cancel(mayInterruptIfRunning);
-    }
-  }
-
-  private static <T> ListenableFuture<T> nonCancellationPropagating(ListenableFuture<T> future) {
-    if (future.isDone()) {
-      return future;
-    }
-    NonCancellationPropagatingFuture<T> output = new NonCancellationPropagatingFuture<T>(future);
-    future.addListener(output, directExecutor());
-    return output;
-  }
-
-  /**
-   * Equivalent to {@code Futures.nonCancellationPropagating}, but allowing us to check whether or
-   * not {@code mayInterruptIfRunning} was set when cancelling it.
-   */
-  private static final class NonCancellationPropagatingFuture<T> extends AbstractFuture<T>
-      implements Runnable {
-    // TODO(cgdecker): This is copied directly from Producers.nonCancellationPropagating, but try
-    // to find out why this doesn't need to be volatile.
-    private ListenableFuture<T> delegate;
-
-    NonCancellationPropagatingFuture(final ListenableFuture<T> delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public void run() {
-      // This prevents cancellation from propagating because we don't call setFuture(delegate) until
-      // delegate is already done, so calling cancel() on this future won't affect it.
-      ListenableFuture<T> localDelegate = delegate;
-      if (localDelegate != null) {
-        setFuture(localDelegate);
-      }
-    }
-
-    @Override
-    protected String pendingToString() {
-      ListenableFuture<T> localDelegate = delegate;
-      if (localDelegate != null) {
-        return "delegate=[" + localDelegate + "]";
-      }
-      return null;
-    }
-
-    @Override
-    protected void afterDone() {
-      delegate = null;
-    }
-
-    public boolean interrupted() {
-      return super.wasInterrupted();
-    }
-  }
-}
diff --git a/java/dagger/producers/internal/AbstractProducesMethodProducer.java b/java/dagger/producers/internal/AbstractProducesMethodProducer.java
deleted file mode 100644
index 0cf36ca..0000000
--- a/java/dagger/producers/internal/AbstractProducesMethodProducer.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.concurrent.Executor;
-import javax.inject.Provider;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/**
- * An {@link AbstractProducer} for all {@link dagger.producers.Produces} methods.
- *
- * @param <D> the type of asynchronous dependencies. These will be collected in {@link
- *     #collectDependencies()} and then made available to the {@code @Produces method in} {@link
- *     #callProducesMethod(Object)}. If there is only one asynchronous dependency, {@code D} can be
- *     the key for that dependency. If there are multiple, they should be wrapped in a list and
- *     unwrapped in {@link #callProducesMethod(Object)}.
- * @param <T> the produced type
- */
-public abstract class AbstractProducesMethodProducer<D, T> extends AbstractProducer<T>
-    implements AsyncFunction<D, T>, Executor {
-  private final Provider<ProductionComponentMonitor> monitorProvider;
-  @NullableDecl private final ProducerToken token;
-  private final Provider<Executor> executorProvider;
-  private volatile ProducerMonitor monitor = null;
-
-  protected AbstractProducesMethodProducer(
-      Provider<ProductionComponentMonitor> monitorProvider,
-      @NullableDecl ProducerToken token,
-      Provider<Executor> executorProvider) {
-    this.monitorProvider = checkNotNull(monitorProvider);
-    this.token = token;
-    this.executorProvider = checkNotNull(executorProvider);
-  }
-
-  @Override
-  protected final ListenableFuture<T> compute() {
-    monitor = monitorProvider.get().producerMonitorFor(token);
-    monitor.requested();
-    ListenableFuture<T> result = Futures.transformAsync(collectDependencies(), this, this);
-    monitor.addCallbackTo(result);
-    return result;
-  }
-
-  /**
-   * Collects the asynchronous dependencies to be passed to {@link
-   * Futures#transformAsync(ListenableFuture, AsyncFunction, Executor)}.
-   */
-  protected abstract ListenableFuture<D> collectDependencies();
-
-  /** @deprecated this may only be called from the internal {@link #compute()} */
-  @Deprecated
-  @Override
-  public final ListenableFuture<T> apply(D asyncDependencies) throws Exception {
-    // NOTE(beder): We don't worry about catching exceptions from the monitor methods themselves
-    // because we'll wrap all monitoring in non-throwing monitors before we pass them to the
-    // factories.
-    monitor.methodStarting();
-    try {
-      return callProducesMethod(asyncDependencies);
-    } finally {
-      monitor.methodFinished();
-    }
-  }
-
-  /**
-   * Calls the {@link dagger.producers.Produces} method. This will always be called on the {@link
-   * Executor} provided to this producer.
-   */
-  protected abstract ListenableFuture<T> callProducesMethod(D asyncDependencies) throws Exception;
-
-  /** @deprecated this may only be called from the internal {@link #compute()} */
-  @Deprecated
-  @Override
-  public final void execute(Runnable runnable) {
-    monitor.ready();
-    executorProvider.get().execute(runnable);
-  }
-}
diff --git a/java/dagger/producers/internal/CancellableProducer.java b/java/dagger/producers/internal/CancellableProducer.java
deleted file mode 100644
index 6a1475e..0000000
--- a/java/dagger/producers/internal/CancellableProducer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import dagger.producers.Producer;
-
-/** A {@link Producer} that can be cancelled directly even if it hasn't been started. */
-public interface CancellableProducer<T> extends Producer<T> {
-
-  /**
-   * Cancels this producer. If {@link #get()} has already been called, the future it returns will be
-   * cancelled if possible. If not, calling {@link #get()} will return a cancelled future and will
-   * not actually start the underlying operation.
-   *
-   * @param mayInterruptIfRunning the value that should be passed to {@code Future.cancel(boolean)}
-   *     for the futures for any running tasks when cancelling them
-   */
-  void cancel(boolean mayInterruptIfRunning);
-
-  /** Returns a new view of this producer for use as a dependency of another node. */
-  Producer<T> newDependencyView();
-
-  /**
-   * Returns a new view of this producer for use as an entry point.
-   *
-   * <p>When the view's future is cancelled, the given {@code cancellableListener} will be called.
-   */
-  Producer<T> newEntryPointView(CancellationListener cancellationListener);
-}
diff --git a/java/dagger/producers/internal/CancellationListener.java b/java/dagger/producers/internal/CancellationListener.java
deleted file mode 100644
index 182ddc6..0000000
--- a/java/dagger/producers/internal/CancellationListener.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-/** A listener for producer future cancellation. */
-public interface CancellationListener {
-  /** Called when the future for a producer this listener has been added to is cancelled. */
-  // Note that this name is intentionally a bit verbose to make it unlikely that it will conflict
-  // with any user-defined methods on a component.
-  void onProducerFutureCancelled(boolean mayInterruptIfRunning);
-}
diff --git a/java/dagger/producers/internal/DelegateProducer.java b/java/dagger/producers/internal/DelegateProducer.java
deleted file mode 100644
index 6cc7547..0000000
--- a/java/dagger/producers/internal/DelegateProducer.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import static dagger.internal.Preconditions.checkNotNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.internal.DoubleCheck;
-import dagger.producers.Producer;
-import javax.inject.Provider;
-
-/**
- * A DelegateProducer that is used to stitch Producer indirection during initialization across
- * partial subcomponent implementations.
- */
-public final class DelegateProducer<T> implements CancellableProducer<T> {
-  private CancellableProducer<T> delegate;
-
-  @Override
-  public ListenableFuture<T> get() {
-    return delegate.get();
-  }
-
-  // TODO(ronshapiro): remove this once we can reasonably expect generated code is no longer using
-  // this method
-  @Deprecated
-  public void setDelegatedProducer(Producer<T> delegate) {
-    setDelegate(this, delegate);
-  }
-
-  /**
-   * Sets {@code delegateProducer}'s delegate producer to {@code delegate}.
-   *
-   * <p>{@code delegateProducer} must be an instance of {@link DelegateProducer}, otherwise this
-   * method will throw a {@link ClassCastException}.
-   */
-  public static <T> void setDelegate(Producer<T> delegateProducer, Producer<T> delegate) {
-    checkNotNull(delegate);
-    DelegateProducer<T> asDelegateProducer = (DelegateProducer<T>) delegateProducer;
-    if (asDelegateProducer.delegate != null) {
-      throw new IllegalStateException();
-    }
-    asDelegateProducer.delegate = (CancellableProducer<T>) delegate;
-  }
-
-  /**
-   * Returns the factory's delegate.
-   *
-   * @throws NullPointerException if the delegate has not been set
-   */
-  CancellableProducer<T> getDelegate() {
-    return checkNotNull(delegate);
-  }
-
-  @Override
-  public void cancel(boolean mayInterruptIfRunning) {
-    delegate.cancel(mayInterruptIfRunning);
-  }
-
-  @Override
-  public Producer<T> newDependencyView() {
-    return new ProducerView<T>() {
-      @Override
-      Producer<T> createDelegate() {
-        return delegate.newDependencyView();
-      }
-    };
-  }
-
-  @Override
-  public Producer<T> newEntryPointView(final CancellationListener cancellationListener) {
-    return new ProducerView<T>() {
-      @Override
-      Producer<T> createDelegate() {
-        return delegate.newEntryPointView(cancellationListener);
-      }
-    };
-  }
-
-  private abstract static class ProducerView<T> implements Producer<T> {
-    private final Provider<Producer<T>> delegate =
-        DoubleCheck.provider(
-            new Provider<Producer<T>>() {
-              @Override
-              public Producer<T> get() {
-                return createDelegate();
-              }
-            });
-
-    abstract Producer<T> createDelegate();
-
-    @Override
-    public ListenableFuture<T> get() {
-      return delegate.get().get();
-    }
-  }
-}
diff --git a/java/dagger/producers/internal/DependencyMethodProducer.java b/java/dagger/producers/internal/DependencyMethodProducer.java
deleted file mode 100644
index be118f2..0000000
--- a/java/dagger/producers/internal/DependencyMethodProducer.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.collect.MapMaker;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Abstract class for implementing producers derived from methods on component dependencies.
- *
- * <p>Unlike most other {@link CancellableProducer} implementations, cancelling the future returned
- * by a {@linkplain #newDependencyView dependency view} injected into an {@code @Produces} method
- * will actually cancel the underlying future. This is because the future comes from outside the
- * component's producer graph (including possibly from another object that isn't a component at
- * all), so if we don't cancel it when the user asks to cancel it, there might just be no way to
- * cancel it at all.
- */
-public abstract class DependencyMethodProducer<T> implements CancellableProducer<T> {
-
-  /** Weak set of all incomplete futures this producer has returned. */
-  private final Set<ListenableFuture<T>> futures =
-      Collections.newSetFromMap(new MapMaker().weakKeys().<ListenableFuture<T>, Boolean>makeMap());
-
-  private boolean cancelled = false;
-
-  /** Calls a method on a component dependency to get a future. */
-  protected abstract ListenableFuture<T> callDependencyMethod();
-
-  @Override
-  public final ListenableFuture<T> get() {
-    synchronized (futures) {
-      if (cancelled) {
-        return Futures.immediateCancelledFuture();
-      }
-
-      final ListenableFuture<T> future = callDependencyMethod();
-      if (!future.isDone() && futures.add(future)) {
-        future.addListener(
-            new Runnable() {
-              @Override
-              public void run() {
-                synchronized (futures) {
-                  futures.remove(future);
-                }
-              }
-            },
-            directExecutor());
-      }
-      return future;
-    }
-  }
-
-  @Override
-  public final void cancel(boolean mayInterruptIfRunning) {
-    synchronized (futures) {
-      cancelled = true;
-      for (ListenableFuture<T> future : futures) {
-        // futures is a concurrent set so that the concurrent removal that will happen here is not
-        // a problem
-        future.cancel(mayInterruptIfRunning);
-      }
-    }
-  }
-
-  @Override
-  public final Producer<T> newDependencyView() {
-    return this;
-  }
-
-  @Override
-  public final Producer<T> newEntryPointView(final CancellationListener cancellationListener) {
-    return new Producer<T>() {
-      private final Set<ListenableFuture<T>> entryPointFutures =
-          Collections.newSetFromMap(
-              new MapMaker().weakKeys().<ListenableFuture<T>, Boolean>makeMap());
-
-      @Override
-      public ListenableFuture<T> get() {
-        final ListenableFuture<T> future = DependencyMethodProducer.this.get();
-        if (!future.isDone() && entryPointFutures.add(future)) {
-          future.addListener(
-              new Runnable() {
-                @Override
-                public void run() {
-                  entryPointFutures.remove(future);
-                  if (future.isCancelled()) {
-                    // TODO(cgdecker): Make this also propagate the actual value that was passed for
-                    // mayInterruptIfRunning
-                    cancellationListener.onProducerFutureCancelled(true);
-                  }
-                }
-              },
-              directExecutor());
-        }
-        return future;
-      }
-    };
-  }
-}
diff --git a/java/dagger/producers/internal/MapOfProducedProducer.java b/java/dagger/producers/internal/MapOfProducedProducer.java
deleted file mode 100644
index bd9f1bf..0000000
--- a/java/dagger/producers/internal/MapOfProducedProducer.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static com.google.common.util.concurrent.Futures.transform;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.List;
-import java.util.Map;
-import javax.inject.Provider;
-
-/**
- * A {@link Producer} implementation used to implement {@link Map} bindings. This producer returns a
- * {@code Map<K, Produced<V>>} which is populated by calls to the delegate {@link Producer#get}
- * methods.
- */
-public final class MapOfProducedProducer<K, V> extends AbstractMapProducer<K, V, Produced<V>> {
-  private MapOfProducedProducer(ImmutableMap<K, Producer<V>> contributingMap) {
-    super(contributingMap);
-  }
-
-  @Override
-  public ListenableFuture<Map<K, Produced<V>>> compute() {
-    return Futures.transform(
-        Futures.allAsList(
-            Iterables.transform(
-                contributingMap().entrySet(), MapOfProducedProducer.<K, V>entryUnwrapper())),
-        new Function<List<Map.Entry<K, Produced<V>>>, Map<K, Produced<V>>>() {
-          @Override
-          public Map<K, Produced<V>> apply(List<Map.Entry<K, Produced<V>>> entries) {
-            return ImmutableMap.copyOf(entries);
-          }
-        },
-        directExecutor());
-  }
-
-  private static final Function<
-          Map.Entry<Object, Producer<Object>>,
-          ListenableFuture<Map.Entry<Object, Produced<Object>>>>
-      ENTRY_UNWRAPPER =
-          new Function<
-              Map.Entry<Object, Producer<Object>>,
-              ListenableFuture<Map.Entry<Object, Produced<Object>>>>() {
-            @Override
-            public ListenableFuture<Map.Entry<Object, Produced<Object>>> apply(
-                final Map.Entry<Object, Producer<Object>> entry) {
-              return transform(
-                  Producers.createFutureProduced(entry.getValue().get()),
-                  new Function<Produced<Object>, Map.Entry<Object, Produced<Object>>>() {
-                    @Override
-                    public Map.Entry<Object, Produced<Object>> apply(Produced<Object> value) {
-                      return Maps.immutableEntry(entry.getKey(), value);
-                    }
-                  },
-                  directExecutor());
-            }
-          };
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // bivariate implementation
-  private static <K, V>
-      Function<Map.Entry<K, Producer<V>>, ListenableFuture<Map.Entry<K, Produced<V>>>>
-          entryUnwrapper() {
-    return (Function) ENTRY_UNWRAPPER;
-  }
-
-  /** Returns a new {@link Builder}. */
-  public static <K, V> Builder<K, V> builder(int size) {
-    return new Builder<>(size);
-  }
-
-  /** A builder for {@link MapOfProducedProducer}. */
-  public static final class Builder<K, V> extends AbstractMapProducer.Builder<K, V, Produced<V>> {
-    private Builder(int size) {
-      super(size);
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Producer<V> producerOfValue) {
-      super.put(key, producerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
-      super.put(key, providerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> putAll(Producer<Map<K, Produced<V>>> mapOfProducedProducer) {
-      super.putAll(mapOfProducedProducer);
-      return this;
-    }
-
-    /** Returns a new {@link MapOfProducedProducer}. */
-    public MapOfProducedProducer<K, V> build() {
-      return new MapOfProducedProducer<>(mapBuilder.build());
-    }
-  }
-}
diff --git a/java/dagger/producers/internal/MapOfProducerProducer.java b/java/dagger/producers/internal/MapOfProducerProducer.java
deleted file mode 100644
index 064cf74..0000000
--- a/java/dagger/producers/internal/MapOfProducerProducer.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static dagger.producers.internal.Producers.entryPointViewOf;
-import static dagger.producers.internal.Producers.nonCancellationPropagatingViewOf;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import java.util.Map;
-import javax.inject.Provider;
-
-/**
- * A {@link Producer} implementation used to implement {@link Map} bindings. This factory returns an
- * immediate future of {@code Map<K, Producer<V>>} when calling {@link #get}.
- */
-public final class MapOfProducerProducer<K, V> extends AbstractMapProducer<K, V, Producer<V>> {
-  /** Returns a new {@link Builder}. */
-  public static <K, V> Builder<K, V> builder(int size) {
-    return new Builder<>(size);
-  }
-
-  private MapOfProducerProducer(ImmutableMap<K, Producer<V>> contributingMap) {
-    super(contributingMap);
-  }
-
-  @Override
-  public ListenableFuture<Map<K, Producer<V>>> compute() {
-    return Futures.<Map<K, Producer<V>>>immediateFuture(contributingMap());
-  }
-
-  /** A builder for {@link MapOfProducerProducer} */
-  public static final class Builder<K, V> extends AbstractMapProducer.Builder<K, V, Producer<V>> {
-    private Builder(int size) {
-      super(size);
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Producer<V> producerOfValue) {
-      super.put(key, producerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
-      super.put(key, providerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> putAll(Producer<Map<K, Producer<V>>> mapOfProducerProducer) {
-      super.putAll(mapOfProducerProducer);
-      return this;
-    }
-
-    /** Returns a new {@link MapOfProducerProducer}. */
-    public MapOfProducerProducer<K, V> build() {
-      return new MapOfProducerProducer<>(mapBuilder.build());
-    }
-  }
-
-  @Override
-  public Producer<Map<K, Producer<V>>> newDependencyView() {
-    return newTransformedValuesView(MapOfProducerProducer.<V>toDependencyView());
-  }
-
-  @Override
-  public Producer<Map<K, Producer<V>>> newEntryPointView(
-      CancellationListener cancellationListener) {
-    return newTransformedValuesView(
-        MapOfProducerProducer.<V>toEntryPointView(cancellationListener));
-  }
-
-  private Producer<Map<K, Producer<V>>> newTransformedValuesView(
-      Function<Producer<V>, Producer<V>> valueTransformationFunction) {
-    return dagger.producers.Producers.<Map<K, Producer<V>>>immediateProducer(
-        ImmutableMap.copyOf(Maps.transformValues(contributingMap(), valueTransformationFunction)));
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <T> Function<Producer<T>, Producer<T>> toDependencyView() {
-    return (Function) TO_DEPENDENCY_VIEW;
-  }
-
-  private static <T> Function<Producer<T>, Producer<T>> toEntryPointView(
-      final CancellationListener cancellationListener) {
-    return new Function<Producer<T>, Producer<T>>() {
-      @Override
-      public Producer<T> apply(Producer<T> input) {
-        return entryPointViewOf(input, cancellationListener);
-      }
-    };
-  }
-
-  private static final Function<Producer<?>, Producer<?>> TO_DEPENDENCY_VIEW =
-      new Function<Producer<?>, Producer<?>>() {
-        @Override
-        public Producer<?> apply(Producer<?> input) {
-          return nonCancellationPropagatingViewOf(input);
-        }
-      };
-}
diff --git a/java/dagger/producers/internal/MapProducer.java b/java/dagger/producers/internal/MapProducer.java
deleted file mode 100644
index 8caeb45..0000000
--- a/java/dagger/producers/internal/MapProducer.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.inject.Provider;
-
-/**
- * A {@link Producer} implementation used to implement {@link Map} bindings. This producer returns a
- * {@code Map<K, V>} which is populated by calls to the delegate {@link Producer#get} methods.
- */
-public final class MapProducer<K, V> extends AbstractMapProducer<K, V, V> {
-  private MapProducer(ImmutableMap<K, Producer<V>> contributingMap) {
-    super(contributingMap);
-  }
-
-  /** Returns a new {@link Builder}. */
-  public static <K, V> Builder<K, V> builder(int size) {
-    return new Builder<>(size);
-  }
-
-  /** A builder for {@link MapProducer} */
-  public static final class Builder<K, V> extends AbstractMapProducer.Builder<K, V, V> {
-    private Builder(int size) {
-      super(size);
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Producer<V> producerOfValue) {
-      super.put(key, producerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> put(K key, Provider<V> providerOfValue) {
-      super.put(key, providerOfValue);
-      return this;
-    }
-
-    @Override
-    public Builder<K, V> putAll(Producer<Map<K, V>> mapProducer) {
-      super.putAll(mapProducer);
-      return this;
-    }
-
-    /** Returns a new {@link MapProducer}. */
-    public MapProducer<K, V> build() {
-      return new MapProducer<>(mapBuilder.build());
-    }
-  }
-
-  @Override
-  protected ListenableFuture<Map<K, V>> compute() {
-    final List<ListenableFuture<Map.Entry<K, V>>> listOfEntries = new ArrayList<>();
-    for (final Entry<K, Producer<V>> entry : contributingMap().entrySet()) {
-      listOfEntries.add(
-          Futures.transform(
-              entry.getValue().get(),
-              new Function<V, Entry<K, V>>() {
-                @Override
-                public Entry<K, V> apply(V computedValue) {
-                  return Maps.immutableEntry(entry.getKey(), computedValue);
-                }
-              },
-              directExecutor()));
-    }
-
-    return Futures.transform(
-        Futures.allAsList(listOfEntries),
-        new Function<List<Map.Entry<K, V>>, Map<K, V>>() {
-          @Override
-          public Map<K, V> apply(List<Map.Entry<K, V>> entries) {
-            return ImmutableMap.copyOf(entries);
-          }
-        },
-        directExecutor());
-  }
-}
diff --git a/java/dagger/producers/internal/MissingBindingProducer.java b/java/dagger/producers/internal/MissingBindingProducer.java
deleted file mode 100644
index 5721569..0000000
--- a/java/dagger/producers/internal/MissingBindingProducer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-
-/**
- * A {@link Producer} that always throws on calls to {@link Producer#get()}. This is necessary in
- * ahead-of-time subcomponents mode, where modifiable binding methods need to return a {@code
- * Producer<T>} to a framework instance initialization that is pruned and no longer in the binding
- * graph, but was present in a superclass implementation. This class fulfills that requirement but
- * is still practically unusable.
- */
-public final class MissingBindingProducer<T> extends AbstractProducer<T> {
-  private static final MissingBindingProducer<Object> INSTANCE = new MissingBindingProducer<>();
-
-  private MissingBindingProducer() {}
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // safe covariant cast
-  public static <T> Producer<T> create() {
-    return (Producer) INSTANCE;
-  }
-
-  @Override
-  protected ListenableFuture<T> compute() {
-    throw new AssertionError(
-        "This binding is not part of the final binding graph. The key was requested by a binding "
-            + "that was believed to possibly be part of the graph, but is no longer requested. "
-            + "If this exception is thrown, it is the result of a Dagger bug.");
-  }
-}
diff --git a/java/dagger/producers/internal/Producers.java b/java/dagger/producers/internal/Producers.java
deleted file mode 100644
index 54e4d5e..0000000
--- a/java/dagger/producers/internal/Producers.java
+++ /dev/null
@@ -1,237 +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.producers.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.Futures.catchingAsync;
-import static com.google.common.util.concurrent.Futures.transform;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Provider;
-
-/**
- * Utility methods for use in generated producer code.
- */
-public final class Producers {
-  /**
-   * Returns a future of {@link Produced} that represents the completion (either success or failure)
-   * of the given future. If the input future succeeds, then the resulting future also succeeds with
-   * a successful {@code Produced}; if the input future fails, then the resulting future succeeds
-   * with a failing {@code Produced}.
-   *
-   * <p>Cancelling the resulting future will propagate the cancellation to the input future; but
-   * cancelling the input future will trigger the resulting future to succeed with a failing
-   * {@code Produced}.
-   */
-  // TODO(beder): Document what happens with an InterruptedException after you figure out how to
-  // trigger one in a test.
-  public static <T> ListenableFuture<Produced<T>> createFutureProduced(ListenableFuture<T> future) {
-    return catchingAsync(
-        transform(future, Producers.<T>resultToProduced(), directExecutor()),
-        Throwable.class,
-        Producers.<T>futureFallbackForProduced(),
-        directExecutor());
-  }
-
-  private static final Function<Object, Produced<Object>> RESULT_TO_PRODUCED =
-      new Function<Object, Produced<Object>>() {
-        @Override
-        public Produced<Object> apply(Object result) {
-          return Produced.successful(result);
-        }
-      };
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // bivariant implementation
-  private static <T> Function<T, Produced<T>> resultToProduced() {
-    return (Function) RESULT_TO_PRODUCED;
-  }
-
-  private static final AsyncFunction<Throwable, Produced<Object>> FUTURE_FALLBACK_FOR_PRODUCED =
-      new AsyncFunction<Throwable, Produced<Object>>() {
-        @Override
-        public ListenableFuture<Produced<Object>> apply(Throwable t) throws Exception {
-          Produced<Object> produced = Produced.failed(t);
-          return Futures.immediateFuture(produced);
-        }
-      };
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // bivariant implementation
-  private static <T> AsyncFunction<Throwable, Produced<T>> futureFallbackForProduced() {
-    return (AsyncFunction) FUTURE_FALLBACK_FOR_PRODUCED;
-  }
-
-  /**
-   * Returns a future of a {@code Set} that contains a single element: the result of the input
-   * future.
-   */
-  public static <T> ListenableFuture<Set<T>> createFutureSingletonSet(ListenableFuture<T> future) {
-    return transform(
-        future,
-        new Function<T, Set<T>>() {
-          @Override
-          public Set<T> apply(T value) {
-            return ImmutableSet.of(value);
-          }
-        },
-        directExecutor());
-  }
-
-  /**
-   * Creates a new {@code ListenableFuture} whose value is a set containing the values of all its
-   * input futures, if all succeed. If any input fails, the returned future fails immediately.
-   *
-   * <p>This is the set equivalent of {@link Futures#allAsList}.
-   */
-  public static <T> ListenableFuture<Set<T>> allAsSet(
-      Iterable<? extends ListenableFuture<? extends T>> futures) {
-    return transform(
-        Futures.allAsList(futures),
-        new Function<List<T>, Set<T>>() {
-          @Override
-          public Set<T> apply(List<T> values) {
-            return ImmutableSet.copyOf(values);
-          }
-        },
-        directExecutor());
-  }
-
-  /**
-   * Returns a producer that immediately executes the binding logic for the given provider every
-   * time it is called.
-   */
-  public static <T> Producer<T> producerFromProvider(final Provider<T> provider) {
-    checkNotNull(provider);
-    return new CompletedProducer<T>() {
-      @Override
-      public ListenableFuture<T> get() {
-        return Futures.immediateFuture(provider.get());
-      }
-    };
-  }
-
-  /**
-   * Returns a producer that succeeds with the given value.
-   *
-   * @deprecated Prefer the non-internal version of this method: {@link
-   * dagger.producers.Producers#immediateProducer(Object)}.
-   */
-  @Deprecated
-  public static <T> Producer<T> immediateProducer(T value) {
-    return dagger.producers.Producers.immediateProducer(value);
-  }
-
-  /**
-   * Returns a producer that fails with the given exception.
-   *
-   * @deprecated Prefer the non-internal version of this method: {@link
-   * dagger.producers.Producers#immediateFailedProducer(Throwable)}.
-   */
-  @Deprecated
-  public static <T> Producer<T> immediateFailedProducer(Throwable throwable) {
-    return dagger.producers.Producers.immediateFailedProducer(throwable);
-  }
-
-  /**
-   * Returns a new view of the given {@code producer} if and only if it is a {@link
-   * CancellableProducer}. Cancelling the returned producer's future will not cancel the underlying
-   * task for the given producer.
-   *
-   * @throws IllegalArgumentException if {@code producer} is not a {@code CancellableProducer}
-   */
-  public static <T> Producer<T> nonCancellationPropagatingViewOf(Producer<T> producer) {
-    // This is a hack until we change the types of Producer fields to be CancellableProducer or
-    // some other type.
-    if (producer instanceof CancellableProducer) {
-      return ((CancellableProducer<T>) producer).newDependencyView();
-    }
-    throw new IllegalArgumentException(
-        "nonCancellationPropagatingViewOf called with non-CancellableProducer: " + producer);
-  }
-
-  /**
-   * Returns a new view of the given {@code producer} for use as an entry point in a production
-   * component, if and only if it is a {@link CancellableProducer}. When the returned producer's
-   * future is cancelled, the given {@code cancellable} will also be cancelled.
-   *
-   * @throws IllegalArgumentException if {@code producer} is not a {@code CancellableProducer}
-   */
-  public static <T> Producer<T> entryPointViewOf(
-      Producer<T> producer, CancellationListener cancellationListener) {
-    // This is a hack until we change the types of Producer fields to be CancellableProducer or
-    // some other type.
-    if (producer instanceof CancellableProducer) {
-      return ((CancellableProducer<T>) producer).newEntryPointView(cancellationListener);
-    }
-    throw new IllegalArgumentException(
-        "entryPointViewOf called with non-CancellableProducer: " + producer);
-  }
-
-  /**
-   * Calls {@code cancel} on the given {@code producer} if it is a {@link CancellableProducer}.
-   *
-   * @throws IllegalArgumentException if {@code producer} is not a {@code CancellableProducer}
-   */
-  public static void cancel(Producer<?> producer, boolean mayInterruptIfRunning) {
-    // This is a hack until we change the types of Producer fields to be CancellableProducer or
-    // some other type.
-    if (producer instanceof CancellableProducer) {
-      ((CancellableProducer<?>) producer).cancel(mayInterruptIfRunning);
-    } else {
-      throw new IllegalArgumentException("cancel called with non-CancellableProducer: " + producer);
-    }
-  }
-
-  private static final Producer<Map<Object, Object>> EMPTY_MAP_PRODUCER =
-      dagger.producers.Producers.<Map<Object, Object>>immediateProducer(ImmutableMap.of());
-
-  @SuppressWarnings("unchecked") // safe contravariant cast
-  public static <K, V> Producer<Map<K, V>> emptyMapProducer() {
-    return (Producer<Map<K, V>>) (Producer) EMPTY_MAP_PRODUCER;
-  }
-
-  /**
-   * A {@link CancellableProducer} which can't be cancelled because it represents an
-   * already-completed task.
-   */
-  private abstract static class CompletedProducer<T> implements CancellableProducer<T> {
-    @Override
-    public void cancel(boolean mayInterruptIfRunning) {}
-
-    @Override
-    public Producer<T> newDependencyView() {
-      return this;
-    }
-
-    @Override
-    public Producer<T> newEntryPointView(CancellationListener cancellationListener) {
-      return this;
-    }
-  }
-
-  private Producers() {}
-}
diff --git a/java/dagger/producers/internal/ProductionExecutorModule.java b/java/dagger/producers/internal/ProductionExecutorModule.java
deleted file mode 100644
index e233ae9..0000000
--- a/java/dagger/producers/internal/ProductionExecutorModule.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 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.producers.internal;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.producers.Production;
-import dagger.producers.ProductionScope;
-import java.util.concurrent.Executor;
-
-/**
- * Binds the {@code @ProductionImplementation Executor} binding in {@link ProductionScope} so that
- * only on instance is ever used within production components.
- */
-@Module
-public abstract class ProductionExecutorModule {
-  @Binds
-  @ProductionScope
-  @ProductionImplementation
-  abstract Executor productionImplementationExecutor(@Production Executor executor);
-
-  private ProductionExecutorModule() {}
-}
diff --git a/java/dagger/producers/internal/ProductionImplementation.java b/java/dagger/producers/internal/ProductionImplementation.java
deleted file mode 100644
index 8a0149c..0000000
--- a/java/dagger/producers/internal/ProductionImplementation.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.internal.Beta;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * Qualifies a type that will be used as an internal implementation detail in the framework.
- *
- * <p>This is only intended to be used by the framework. It is the internal counterpart to
- * {@link dagger.producers.Production}.
- */
-@Documented
-@Retention(RUNTIME)
-@Qualifier
-@Beta
-public @interface ProductionImplementation {}
diff --git a/java/dagger/producers/internal/SetOfProducedProducer.java b/java/dagger/producers/internal/SetOfProducedProducer.java
deleted file mode 100644
index 40833e5..0000000
--- a/java/dagger/producers/internal/SetOfProducedProducer.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-import static dagger.internal.DaggerCollections.hasDuplicates;
-import static dagger.internal.DaggerCollections.presizedList;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-
-/**
- * A {@link Producer} implementation used to implement {@link Set} bindings. This producer returns a
- * future {@code Set<Produced<T>>} whose elements are populated by subsequent calls to the delegate
- * {@link Producer#get} methods.
- */
-public final class SetOfProducedProducer<T> extends AbstractProducer<Set<Produced<T>>> {
-  public static <T> Producer<Set<T>> empty() {
-    return SetProducer.empty();
-  }
-
-  /**
-   * Constructs a new {@link Builder} for a {@link SetProducer} with {@code individualProducerSize}
-   * individual {@code Producer<T>} and {@code collectionProducerSize} {@code
-   * Producer<Collection<T>>} instances.
-   */
-  public static <T> Builder<T> builder(int individualProducerSize, int collectionProducerSize) {
-    return new Builder<T>(individualProducerSize, collectionProducerSize);
-  }
-
-  /**
-   * A builder to accumulate {@code Producer<T>} and {@code Producer<Collection<T>>} instances.
-   * These are only intended to be single-use and from within generated code. Do <em>NOT</em> add
-   * producers after calling {@link #build()}.
-   */
-  public static final class Builder<T> {
-    private final List<Producer<T>> individualProducers;
-    private final List<Producer<Collection<T>>> collectionProducers;
-
-    private Builder(int individualProducerSize, int collectionProducerSize) {
-      individualProducers = presizedList(individualProducerSize);
-      collectionProducers = presizedList(collectionProducerSize);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addProducer(Producer<? extends T> individualProducer) {
-      assert individualProducer != null : "Codegen error? Null producer";
-      individualProducers.add((Producer<T>) individualProducer);
-      return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addCollectionProducer(
-        Producer<? extends Collection<? extends T>> multipleProducer) {
-      assert multipleProducer != null : "Codegen error? Null producer";
-      collectionProducers.add((Producer<Collection<T>>) multipleProducer);
-      return this;
-    }
-
-    public SetOfProducedProducer<T> build() {
-      assert !hasDuplicates(individualProducers)
-          : "Codegen error?  Duplicates in the producer list";
-      assert !hasDuplicates(collectionProducers)
-          : "Codegen error?  Duplicates in the producer list";
-
-      return new SetOfProducedProducer<T>(individualProducers, collectionProducers);
-    }
-  }
-
-  private final List<Producer<T>> individualProducers;
-  private final List<Producer<Collection<T>>> collectionProducers;
-
-  private SetOfProducedProducer(
-      List<Producer<T>> individualProducers, List<Producer<Collection<T>>> collectionProducers) {
-    this.individualProducers = individualProducers;
-    this.collectionProducers = collectionProducers;
-  }
-
-  /**
-   * Returns a future {@link Set} of {@link Produced} elements given by each of the producers.
-   *
-   * <p>If any of the delegate collections, or any elements therein, are null, then that
-   * corresponding {@code Produced} element will fail with a NullPointerException.
-   *
-   * <p>Canceling this future will attempt to cancel all of the component futures; but if any of the
-   * delegate futures fail or are canceled, this future succeeds, with the appropriate failed {@link
-   * Produced}.
-   *
-   * @throws NullPointerException if any of the delegate producers return null
-   */
-  @Override
-  public ListenableFuture<Set<Produced<T>>> compute() {
-    List<ListenableFuture<? extends Produced<? extends Collection<T>>>> futureProducedCollections =
-        new ArrayList<ListenableFuture<? extends Produced<? extends Collection<T>>>>(
-            individualProducers.size() + collectionProducers.size());
-    for (Producer<T> producer : individualProducers) {
-      // TODO(ronshapiro): Don't require individual productions to be added to a collection just to
-      // be materialized into futureProducedCollections.
-      futureProducedCollections.add(
-          Producers.createFutureProduced(
-              Producers.createFutureSingletonSet(checkNotNull(producer.get()))));
-    }
-    for (Producer<Collection<T>> producer : collectionProducers) {
-      futureProducedCollections.add(Producers.createFutureProduced(checkNotNull(producer.get())));
-    }
-
-    return Futures.transform(
-        Futures.allAsList(futureProducedCollections),
-        new Function<List<Produced<? extends Collection<T>>>, Set<Produced<T>>>() {
-          @Override
-          public Set<Produced<T>> apply(
-              List<Produced<? extends Collection<T>>> producedCollections) {
-            ImmutableSet.Builder<Produced<T>> builder = ImmutableSet.builder();
-            for (Produced<? extends Collection<T>> producedCollection : producedCollections) {
-              try {
-                Collection<T> collection = producedCollection.get();
-                if (collection == null) {
-                  // TODO(beder): This is a vague exception. Can we somehow point to the failing
-                  // producer? See the similar comment in the component writer about null
-                  // provisions.
-                  builder.add(
-                      Produced.<T>failed(
-                          new NullPointerException(
-                              "Cannot contribute a null collection into a producer set binding when"
-                                  + " it's injected as Set<Produced<T>>.")));
-                } else {
-                  for (T value : collection) {
-                    if (value == null) {
-                      builder.add(
-                          Produced.<T>failed(
-                              new NullPointerException(
-                                  "Cannot contribute a null element into a producer set binding"
-                                      + " when it's injected as Set<Produced<T>>.")));
-                    } else {
-                      builder.add(Produced.successful(value));
-                    }
-                  }
-                }
-              } catch (ExecutionException e) {
-                builder.add(Produced.<T>failed(e.getCause()));
-              }
-            }
-            return builder.build();
-          }
-        },
-        directExecutor());
-  }
-}
diff --git a/java/dagger/producers/internal/SetProducer.java b/java/dagger/producers/internal/SetProducer.java
deleted file mode 100644
index c0196ae..0000000
--- a/java/dagger/producers/internal/SetProducer.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.Futures.transform;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-import static dagger.internal.DaggerCollections.hasDuplicates;
-import static dagger.internal.DaggerCollections.presizedList;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A {@link Producer} implementation used to implement {@link Set} bindings. This producer returns
- * a future {@link Set} whose elements are populated by subsequent calls to the delegate
- * {@link Producer#get} methods.
- */
-public final class SetProducer<T> extends AbstractProducer<Set<T>> {
-  private static final Producer<Set<Object>> EMPTY_PRODUCER =
-      dagger.producers.Producers.<Set<Object>>immediateProducer(ImmutableSet.<Object>of());
-
-  @SuppressWarnings({"unchecked", "rawtypes"}) // safe covariant cast
-  public static <T> Producer<Set<T>> empty() {
-    return (Producer) EMPTY_PRODUCER;
-  }
-
-  /**
-   * Constructs a new {@link Builder} for a {@link SetProducer} with {@code individualProducerSize}
-   * individual {@code Producer<T>} and {@code collectionProducerSize} {@code
-   * Producer<Collection<T>>} instances.
-   */
-  public static <T> Builder<T> builder(int individualProducerSize, int collectionProducerSize) {
-    return new Builder<T>(individualProducerSize, collectionProducerSize);
-  }
-
-  /**
-   * A builder to accumulate {@code Producer<T>} and {@code Producer<Collection<T>>} instances.
-   * These are only intended to be single-use and from within generated code. Do <em>NOT</em> add
-   * producers after calling {@link #build()}.
-   */
-  public static final class Builder<T> {
-    private final List<Producer<T>> individualProducers;
-    private final List<Producer<Collection<T>>> collectionProducers;
-
-    private Builder(int individualProducerSize, int collectionProducerSize) {
-      individualProducers = presizedList(individualProducerSize);
-      collectionProducers = presizedList(collectionProducerSize);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addProducer(Producer<? extends T> individualProducer) {
-      assert individualProducer != null : "Codegen error? Null producer";
-      individualProducers.add((Producer<T>) individualProducer);
-      return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public Builder<T> addCollectionProducer(
-        Producer<? extends Collection<? extends T>> multipleProducer) {
-      assert multipleProducer != null : "Codegen error? Null producer";
-      collectionProducers.add((Producer<Collection<T>>) multipleProducer);
-      return this;
-    }
-
-    public SetProducer<T> build() {
-      assert !hasDuplicates(individualProducers)
-          : "Codegen error?  Duplicates in the producer list";
-      assert !hasDuplicates(collectionProducers)
-          : "Codegen error?  Duplicates in the producer list";
-
-      return new SetProducer<T>(individualProducers, collectionProducers);
-    }
-  }
-
-  private final List<Producer<T>> individualProducers;
-  private final List<Producer<Collection<T>>> collectionProducers;
-
-  private SetProducer(
-      List<Producer<T>> individualProducers, List<Producer<Collection<T>>> collectionProducers) {
-    this.individualProducers = individualProducers;
-    this.collectionProducers = collectionProducers;
-  }
-
-  /**
-   * Returns a future {@link Set} that contains the elements given by each of the producers.
-   *
-   * <p>If any of the delegate collections, or any elements therein, are null, then this future will
-   * fail with a NullPointerException.
-   *
-   * <p>Canceling this future will attempt to cancel all of the component futures, and if any of the
-   * delegate futures fails or is canceled, this one is, too.
-   *
-   * @throws NullPointerException if any of the delegate producers return null
-   */
-  @Override
-  public ListenableFuture<Set<T>> compute() {
-    List<ListenableFuture<T>> individualFutures =
-        new ArrayList<ListenableFuture<T>>(individualProducers.size());
-    for (Producer<T> producer : individualProducers) {
-      individualFutures.add(checkNotNull(producer.get()));
-    }
-
-    // Presize the list of collections produced by the amount of collectionProducers, with one more
-    // for the consolidate individualFutures from Futures.allAsList.
-    List<ListenableFuture<? extends Collection<T>>> futureCollections =
-        new ArrayList<ListenableFuture<? extends Collection<T>>>(collectionProducers.size() + 1);
-    futureCollections.add(Futures.allAsList(individualFutures));
-    for (Producer<Collection<T>> producer : collectionProducers) {
-      futureCollections.add(checkNotNull(producer.get()));
-    }
-    return transform(
-        Futures.allAsList(futureCollections),
-        new Function<List<Collection<T>>, Set<T>>() {
-          @Override
-          public Set<T> apply(List<Collection<T>> sets) {
-            ImmutableSet.Builder<T> builder = ImmutableSet.builder();
-            for (Collection<T> set : sets) {
-              builder.addAll(set);
-            }
-            return builder.build();
-          }
-        },
-        directExecutor());
-  }
-}
diff --git a/java/dagger/producers/monitoring/ProducerMonitor.java b/java/dagger/producers/monitoring/ProducerMonitor.java
deleted file mode 100644
index c0379fd..0000000
--- a/java/dagger/producers/monitoring/ProducerMonitor.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import static com.google.common.util.concurrent.Futures.addCallback;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import dagger.producers.Produces;
-
-/**
- * A hook for monitoring the execution of individual {@linkplain Produces producer methods}. See
- * {@link ProductionComponentMonitor} for how to install these monitors.
- *
- * <p>The lifecycle of the monitor, under normal conditions, is:
- * <ul>
- *   <li>{@link #requested()}
- *   <li>{@link #methodStarting()}
- *   <li>The method is called
- *   <li>{@link #methodFinished()}
- *   <li>If the method returns a value, then:
- *   <ul>
- *     <li>{@link #succeeded(Object)} if the method returned normally; or
- *     <li>{@link #failed(Throwable)} if the method threw an exception.
- *   </ul>
- *   <li>If the method returns a future, then:
- *   <ul>
- *     <li>{@link #succeeded(Object)} if the method returned normally, and the future succeeded; or
- *     <li>{@link #failed(Throwable)} if the method threw an exception, or returned normally and the
- *         future failed.
- *   </ul>
- * </ul>
- *
- * <p>If any input to the monitored producer fails, {@link #failed(Throwable)} will be called
- * immediately with the failed input's exception. If more than one input fails, an arbitrary failed
- * input's exception is used.
- *
- * <p>For example, given an entry point A that depends on B, which depends on C, when the entry
- * point A is called, this will trigger the following sequence of events, assuming all methods and
- * futures complete successfully:
- * <ul>
- *   <li>A requested
- *   <li>B requested
- *   <li>C requested
- *   <li>C methodStarting
- *   <li>C methodFinished
- *   <li>C succeeded
- *   <li>B methodStarting
- *   <li>B methodFinished
- *   <li>B succeeded
- *   <li>A methodStarting
- *   <li>A methodFinished
- *   <li>A succeeded
- * </ul>
- *
- * <p>If any of the monitor's methods throw, then the exception will be logged and processing will
- * continue unaffected.
- *
- * @since 2.1
- */
-public abstract class ProducerMonitor {
-  /**
-   * Called when the producer's output is requested; that is, when the first method is called that
-   * requires the production of this producer's output.
-   *
-   * <p>Note that if a method depends on {@code Producer<T>}, then this does not count as requesting
-   * {@code T}; that is only triggered by calling {@link Producer#get()}.
-   *
-   * <p>Depending on how this producer is requested, the following threading constraints are
-   * guaranteed:
-   *
-   * <ol>
-   *   <li>If the producer is requested directly by a method on a component, then {@code requested}
-   *       will be called on the same thread as the component method call.
-   *   <li>If the producer is requested by value from another producer (i.e., injected as {@code T}
-   *       or {@code Produced<T>}), then {@code requested} will be called from the same thread as
-   *       the other producer's {@code requested}.
-   *   <li>If the producer is requested by calling {@link Producer#get()}, then {@code requested}
-   *       will be called from the same thread as that {@code get()} call.
-   * </ol>
-   *
-   * <p>When multiple monitors are installed, the order that each monitor will call this method is
-   * unspecified, but will remain consistent throughout the course of the execution of a component.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void requested() {}
-
-  /**
-   * Called when all of the producer's inputs are available. This is called regardless of whether
-   * the inputs have succeeded or not; when the inputs have succeeded, this is called prior to
-   * scheduling the method on the executor, and if an input has failed and the producer will be
-   * skipped, this method will be called before {@link #failed(Throwable)} is called.
-   *
-   * <p>When multiple monitors are installed, the order that each monitor will call this method is
-   * unspecified, but will remain consistent throughout the course of the execution of a component.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void ready() {}
-
-  /**
-   * Called when the producer method is about to start executing. This will be called from the same
-   * thread as the producer method itself.
-   *
-   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
-   * calls to {@link #requested()}.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void methodStarting() {}
-
-  /**
-   * Called when the producer method has finished executing. This will be called from the same
-   * thread as {@link #methodStarting()} and the producer method itself.
-   *
-   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
-   * calls to {@link #requested()}.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void methodFinished() {}
-
-  /**
-   * Called when the producer’s future has completed successfully with a value.
-   *
-   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
-   * calls to {@link #requested()}.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void succeeded(@SuppressWarnings("unused") Object value) {}
-
-  /**
-   * Called when the producer's future has failed with an exception.
-   *
-   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
-   * calls to {@link #requested()}.
-   *
-   * <p>This implementation is a no-op.
-   */
-  public void failed(@SuppressWarnings("unused") Throwable t) {}
-
-  /**
-   * Adds this monitor's completion methods as a callback to the future. This is only intended to be
-   * overridden in the framework!
-   */
-  public <T> void addCallbackTo(ListenableFuture<T> future) {
-    addCallback(
-        future,
-        new FutureCallback<T>() {
-          @Override
-          public void onSuccess(T value) {
-            succeeded(value);
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            failed(t);
-          }
-        },
-        directExecutor());
-  }
-
-  private static final ProducerMonitor NO_OP =
-      new ProducerMonitor() {
-        @Override
-        public <T> void addCallbackTo(ListenableFuture<T> future) {
-          // overridden to avoid adding a do-nothing callback
-        }
-      };
-
-  /** Returns a monitor that does no monitoring. */
-  public static ProducerMonitor noOp() {
-    return NO_OP;
-  }
-}
diff --git a/java/dagger/producers/monitoring/ProducerTimingRecorder.java b/java/dagger/producers/monitoring/ProducerTimingRecorder.java
deleted file mode 100644
index f4894c9..0000000
--- a/java/dagger/producers/monitoring/ProducerTimingRecorder.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-
-/**
- * A hook for recording the timing of the execution of individual
- * {@linkplain Produces producer methods}. See {@link ProductionComponentTimingRecorder} for how to
- * install these monitors.
- *
- * <p>If any of the recorder's methods throw, then the exception will be logged and processing will
- * continue unaffected.
- *
- * <p>All timings are measured at nanosecond precision, but not necessarily nanosecond resolution.
- * That is, timings will be reported in nanoseconds, but the timing source will not necessarily
- * update at nanosecond resolution. For example, {@link System#nanoTime()} would satisfy these
- * constraints.
- *
- * @since 2.1
- */
-public abstract class ProducerTimingRecorder {
-  /**
-   * Reports that the producer method has finished executing with the given statistics.
-   *
-   * <p>If the producer was skipped due to any of its inputs failing, then this will not be called.
-   *
-   * @param startedNanos the wall-clock time, in nanoseconds, when the producer method started
-   *     executing, measured from when the first method on the {@linkplain ProductionComponent
-   *     production component} was called.
-   * @param durationNanos the wall-clock time, in nanoseconds, that the producer method took to
-   *     execute.
-   */
-  @SuppressWarnings("GoodTime") // should accept a java.time.Duration x2 (?)
-  public void recordMethod(long startedNanos, long durationNanos) {}
-
-  /**
-   * Reports that the producer's future has succeeded with the given statistics.
-   *
-   * <p>If the producer was skipped due to any of its inputs failing, then this will not be called.
-   *
-   * @param latencyNanos the wall-clock time, in nanoseconds, of the producer's latency, measured
-   *     from when the producer method started to when the future finished.
-   */
-  @SuppressWarnings("GoodTime") // should accept a java.time.Duration
-  public void recordSuccess(long latencyNanos) {}
-
-  /**
-   * Reports that the producer's future has failed with the given statistics.
-   *
-   * @param exception the exception that the future failed with.
-   * @param latencyNanos the wall-clock time, in nanoseconds, of the producer's latency, measured
-   *     from when the producer method started to when the future finished.
-   */
-  @SuppressWarnings("GoodTime") // should accept a java.time.Duration
-  public void recordFailure(Throwable exception, long latencyNanos) {}
-
-  /**
-   * Reports that the producer was skipped because one of its inputs failed.
-   *
-   * @param exception the exception that its input failed with. If multiple inputs failed, this
-   *    exception will be chosen arbitrarily from the input failures.
-   */
-  public void recordSkip(Throwable exception) {}
-
-  /** Returns a producer recorder that does nothing. */
-  public static ProducerTimingRecorder noOp() {
-    return NO_OP;
-  }
-
-  private static final ProducerTimingRecorder NO_OP = new ProducerTimingRecorder() {};
-}
diff --git a/java/dagger/producers/monitoring/ProducerToken.java b/java/dagger/producers/monitoring/ProducerToken.java
deleted file mode 100644
index 1f05146..0000000
--- a/java/dagger/producers/monitoring/ProducerToken.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import dagger.producers.Produces;
-import java.util.Objects;
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
-/** A token that represents an individual {@linkplain Produces producer method}. */
-public final class ProducerToken {
-  @NullableDecl private final Class<?> classToken;
-  @NullableDecl private final String methodName;
-
-  private ProducerToken(@NullableDecl Class<?> classToken, @NullableDecl String methodName) {
-    this.classToken = classToken;
-    this.methodName = methodName;
-  }
-
-  /**
-   * Creates a token for a class token that represents the generated factory for a producer method.
-   *
-   * <p><b>Do not use this!</b> This is intended to be called by generated code only, and its
-   * signature may change at any time.
-   */
-  public static ProducerToken create(Class<?> classToken) {
-    return new ProducerToken(checkNotNull(classToken), null);
-  }
-
-  /**
-   * Creates a token for a producer method.
-   *
-   * <p><b>Do not use this!</b> This is intended to be called by generated code only, and its
-   * signature may change at any time.
-   */
-  public static ProducerToken create(String methodName) {
-    return new ProducerToken(null, checkNotNull(methodName));
-  }
-
-  /** Two tokens are equal if they represent the same method. */
-  @Override
-  public boolean equals(Object o) {
-    if (o == this) {
-      return true;
-    } else if (o instanceof ProducerToken) {
-      ProducerToken that = (ProducerToken) o;
-      return Objects.equals(this.classToken, that.classToken)
-          && Objects.equals(this.methodName, that.methodName);
-    } else {
-      return false;
-    }
-  }
-
-  /** Returns an appropriate hash code to match {@link #equals(Object)}. */
-  @Override
-  public int hashCode() {
-    int h = 1;
-    h *= 1000003;
-    h ^= Objects.hashCode(this.classToken);
-    h *= 1000003;
-    h ^= Objects.hashCode(this.methodName);
-    return h;
-  }
-
-  /** Returns a representation of the method. */
-  @Override
-  public String toString() {
-    if (methodName != null) {
-      return methodName;
-    } else if (classToken != null) {
-      return classToken.getCanonicalName();
-    } else {
-      throw new IllegalStateException();
-    }
-  }
-}
diff --git a/java/dagger/producers/monitoring/ProductionComponentMonitor.java b/java/dagger/producers/monitoring/ProductionComponentMonitor.java
deleted file mode 100644
index ca71ece..0000000
--- a/java/dagger/producers/monitoring/ProductionComponentMonitor.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-
-/**
- * A hook for monitoring execution of {@linkplain ProductionComponent production components}. To
- * install a {@code ProductionComponentMonitor}, contribute to a set binding of
- * {@code ProductionComponentMonitor.Factory}. The factory will be asked to create one monitor for
- * the component, and the resulting single instance will be used to create individual monitors for
- * producers.
- *
- * <p>For example: <pre><code>
- *   {@literal @Module}
- *   final class MyMonitorModule {
- *     {@literal @Provides @IntoSet} ProductionComponentMonitor.Factory provideMonitorFactory(
- *         MyProductionComponentMonitor.Factory monitorFactory) {
- *       return monitorFactory;
- *     }
- *   }
- *
- *   {@literal @ProductionComponent(modules = {MyMonitorModule.class, MyProducerModule.class})}
- *   interface MyComponent {
- *     {@literal ListenableFuture<SomeType>} someType();
- *   }
- * </code></pre>
- *
- * <p>If any of these methods throw, then the exception will be logged, and the framework will act
- * as though a no-op monitor was returned.
- *
- * @since 2.1
- */
-public abstract class ProductionComponentMonitor {
-  /** Returns a monitor for an individual {@linkplain Produces producer method}. */
-  public abstract ProducerMonitor producerMonitorFor(ProducerToken token);
-
-  private static final ProductionComponentMonitor NO_OP =
-      new ProductionComponentMonitor() {
-        @Override
-        public ProducerMonitor producerMonitorFor(ProducerToken token) {
-          return ProducerMonitor.noOp();
-        }
-      };
-
-  /** Returns a monitor that does no monitoring. */
-  public static ProductionComponentMonitor noOp() {
-    return NO_OP;
-  }
-
-  public abstract static class Factory {
-    /** Creates a component-specific monitor when the component is created. */
-    public abstract ProductionComponentMonitor create(Object component);
-
-    private static final Factory NO_OP_FACTORY =
-        new Factory() {
-          @Override
-          public ProductionComponentMonitor create(Object component) {
-            return ProductionComponentMonitor.noOp();
-          }
-        };
-
-    /** Returns a factory that returns no-op monitors. */
-    public static Factory noOp() {
-      return NO_OP_FACTORY;
-    }
-  }
-}
diff --git a/java/dagger/producers/monitoring/ProductionComponentTimingRecorder.java b/java/dagger/producers/monitoring/ProductionComponentTimingRecorder.java
deleted file mode 100644
index d82d8e1..0000000
--- a/java/dagger/producers/monitoring/ProductionComponentTimingRecorder.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-
-/**
- * A hook for recording timing of the execution of
- * {@linkplain ProductionComponent production components}. To install a
- * {@code ProductionComponentTimingRecorder}, contribute to a set binding of
- * {@code ProductionComponentTimingRecorder.Factory}, and include the {@code TimingMonitorModule} to
- * the component. The factory will be asked to create one timing recorder for the component, and the
- * resulting instance will be used to create individual timing recorders for producers.
- *
- * <p>If any of these methods throw, then the exception will be logged, and the framework will act
- * as though a no-op timing recorder was returned.
- *
- * @since 2.1
- */
-public interface ProductionComponentTimingRecorder {
-  /** Returns a timing recorder for an individual {@linkplain Produces producer method}. */
-  ProducerTimingRecorder producerTimingRecorderFor(ProducerToken token);
-
-  public interface Factory {
-    /** Creates a component-specific timing recorder when the component is created. */
-    ProductionComponentTimingRecorder create(Object component);
-  }
-}
diff --git a/java/dagger/producers/monitoring/TimingProducerMonitor.java b/java/dagger/producers/monitoring/TimingProducerMonitor.java
deleted file mode 100644
index c63e108..0000000
--- a/java/dagger/producers/monitoring/TimingProducerMonitor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Ticker;
-
-/**
- * A monitor that measures the timing of the execution of a producer method, and logs those timings
- * with the given recorder.
- */
-final class TimingProducerMonitor extends ProducerMonitor {
-  private final ProducerTimingRecorder recorder;
-  private final Stopwatch stopwatch;
-  private final Stopwatch componentStopwatch;
-  private long startNanos = -1;
-
-  TimingProducerMonitor(
-      ProducerTimingRecorder recorder, Ticker ticker, Stopwatch componentStopwatch) {
-    this.recorder = recorder;
-    this.stopwatch = Stopwatch.createUnstarted(ticker);
-    this.componentStopwatch = componentStopwatch;
-  }
-
-  @Override
-  public void methodStarting() {
-    startNanos = componentStopwatch.elapsed(NANOSECONDS);
-    stopwatch.start();
-  }
-
-  @Override
-  public void methodFinished() {
-    // TODO(beder): Is a system ticker the appropriate way to track CPU time? Should we use
-    // ThreadCpuTicker instead?
-    long durationNanos = stopwatch.elapsed(NANOSECONDS);
-    recorder.recordMethod(startNanos, durationNanos);
-  }
-
-  @Override
-  public void succeeded(Object o) {
-    long latencyNanos = stopwatch.elapsed(NANOSECONDS);
-    recorder.recordSuccess(latencyNanos);
-  }
-
-  @Override
-  public void failed(Throwable t) {
-    if (stopwatch.isRunning()) {
-      long latencyNanos = stopwatch.elapsed(NANOSECONDS);
-      recorder.recordFailure(t, latencyNanos);
-    } else {
-      recorder.recordSkip(t);
-    }
-  }
-}
diff --git a/java/dagger/producers/monitoring/TimingProductionComponentMonitor.java b/java/dagger/producers/monitoring/TimingProductionComponentMonitor.java
deleted file mode 100644
index 66589d9..0000000
--- a/java/dagger/producers/monitoring/TimingProductionComponentMonitor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Ticker;
-import dagger.internal.Beta;
-
-/**
- * A monitor that measures the timing of the execution of a production component, and logs those
- * timings with the given recorder.
- *
- * <p>This assumes that the given recorders do not throw or return null; for example, by using
- * {@link TimingRecorders#delegatingProductionComponentTimingRecorderFactory}.
- */
-// TODO(beder): Reduce the visibility of this class to package-private.
-@Beta
-public final class TimingProductionComponentMonitor extends ProductionComponentMonitor {
-  private final ProductionComponentTimingRecorder recorder;
-  private final Ticker ticker;
-  private final Stopwatch stopwatch;
-
-  TimingProductionComponentMonitor(ProductionComponentTimingRecorder recorder, Ticker ticker) {
-    this.recorder = recorder;
-    this.ticker = ticker;
-    this.stopwatch = Stopwatch.createStarted(ticker);
-  }
-
-  @Override
-  public ProducerMonitor producerMonitorFor(ProducerToken token) {
-    return new TimingProducerMonitor(recorder.producerTimingRecorderFor(token), ticker, stopwatch);
-  }
-
-  public static final class Factory extends ProductionComponentMonitor.Factory {
-    private final ProductionComponentTimingRecorder.Factory recorderFactory;
-    private final Ticker ticker;
-
-    public Factory(ProductionComponentTimingRecorder.Factory recorderFactory) {
-      this(recorderFactory, Ticker.systemTicker());
-    }
-
-    Factory(ProductionComponentTimingRecorder.Factory recorderFactory, Ticker ticker) {
-      this.recorderFactory = recorderFactory;
-      this.ticker = ticker;
-    }
-
-    @Override
-    public ProductionComponentMonitor create(Object component) {
-      return new TimingProductionComponentMonitor(recorderFactory.create(component), ticker);
-    }
-  }
-}
diff --git a/java/dagger/producers/monitoring/TimingRecorders.java b/java/dagger/producers/monitoring/TimingRecorders.java
deleted file mode 100644
index 5fbe3e3..0000000
--- a/java/dagger/producers/monitoring/TimingRecorders.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import dagger.internal.Beta;
-import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Utility methods relating to timing.
- *
- * @since 2.1
- */
-// TODO(beder): Reduce the visibility of this class to package-private.
-@Beta
-public final class TimingRecorders {
-  private static final Logger logger = Logger.getLogger(TimingRecorders.class.getName());
-
-  /**
-   * Returns a timing recorder factory that delegates to the given factories, and ensures that any
-   * method called on this object, even transitively, does not throw a {@link RuntimeException} or
-   * return null.
-   *
-   * <p>If the delegate recorders throw an {@link Error}, then that will escape this recorder
-   * implementation. Errors are treated as unrecoverable conditions, and may cause the entire
-   * component's execution to fail.
-   */
-  public static ProductionComponentTimingRecorder.Factory
-      delegatingProductionComponentTimingRecorderFactory(
-          Collection<ProductionComponentTimingRecorder.Factory> factories) {
-    switch (factories.size()) {
-      case 0:
-        return noOpProductionComponentTimingRecorderFactory();
-      case 1:
-        return new NonThrowingProductionComponentTimingRecorder.Factory(
-            Iterables.getOnlyElement(factories));
-      default:
-        return new DelegatingProductionComponentTimingRecorder.Factory(factories);
-    }
-  }
-
-  /**
-   * A component recorder that delegates to a single recorder, and catches and logs all exceptions
-   * that the delegate throws.
-   */
-  private static final class NonThrowingProductionComponentTimingRecorder
-      implements ProductionComponentTimingRecorder {
-    private final ProductionComponentTimingRecorder delegate;
-
-    NonThrowingProductionComponentTimingRecorder(ProductionComponentTimingRecorder delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public ProducerTimingRecorder producerTimingRecorderFor(ProducerToken token) {
-      try {
-        ProducerTimingRecorder recorder = delegate.producerTimingRecorderFor(token);
-        return recorder == null
-            ? ProducerTimingRecorder.noOp()
-            : new NonThrowingProducerTimingRecorder(recorder);
-      } catch (RuntimeException e) {
-        logProducerTimingRecorderForException(e, delegate, token);
-        return ProducerTimingRecorder.noOp();
-      }
-    }
-
-    static final class Factory implements ProductionComponentTimingRecorder.Factory {
-      private final ProductionComponentTimingRecorder.Factory delegate;
-
-      Factory(ProductionComponentTimingRecorder.Factory delegate) {
-        this.delegate = delegate;
-      }
-
-      @Override
-      public ProductionComponentTimingRecorder create(Object component) {
-        try {
-          ProductionComponentTimingRecorder recorder = delegate.create(component);
-          return recorder == null
-              ? noOpProductionComponentTimingRecorder()
-              : new NonThrowingProductionComponentTimingRecorder(recorder);
-        } catch (RuntimeException e) {
-          logCreateException(e, delegate, component);
-          return noOpProductionComponentTimingRecorder();
-        }
-      }
-    }
-  }
-
-  /**
-   * A producer recorder that delegates to a single recorder, and catches and logs all exceptions
-   * that the delegate throws.
-   */
-  private static final class NonThrowingProducerTimingRecorder extends ProducerTimingRecorder {
-    private final ProducerTimingRecorder delegate;
-
-    NonThrowingProducerTimingRecorder(ProducerTimingRecorder delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public void recordMethod(long startedNanos, long durationNanos) {
-      try {
-        delegate.recordMethod(startedNanos, durationNanos);
-      } catch (RuntimeException e) {
-        logProducerTimingRecorderMethodException(e, delegate, "recordMethod");
-      }
-    }
-
-    @Override
-    public void recordSuccess(long latencyNanos) {
-      try {
-        delegate.recordSuccess(latencyNanos);
-      } catch (RuntimeException e) {
-        logProducerTimingRecorderMethodException(e, delegate, "recordSuccess");
-      }
-    }
-
-    @Override
-    public void recordFailure(Throwable exception, long latencyNanos) {
-      try {
-        delegate.recordFailure(exception, latencyNanos);
-      } catch (RuntimeException e) {
-        logProducerTimingRecorderMethodException(e, delegate, "recordFailure");
-      }
-    }
-
-    @Override
-    public void recordSkip(Throwable exception) {
-      try {
-        delegate.recordSkip(exception);
-      } catch (RuntimeException e) {
-        logProducerTimingRecorderMethodException(e, delegate, "recordSkip");
-      }
-    }
-  }
-
-  /**
-   * A component recorder that delegates to several recorders, and catches and logs all exceptions
-   * that the delegates throw.
-   */
-  private static final class DelegatingProductionComponentTimingRecorder
-      implements ProductionComponentTimingRecorder {
-    private final ImmutableList<ProductionComponentTimingRecorder> delegates;
-
-    DelegatingProductionComponentTimingRecorder(
-        ImmutableList<ProductionComponentTimingRecorder> delegates) {
-      this.delegates = delegates;
-    }
-
-    @Override
-    public ProducerTimingRecorder producerTimingRecorderFor(ProducerToken token) {
-      ImmutableList.Builder<ProducerTimingRecorder> recordersBuilder = ImmutableList.builder();
-      for (ProductionComponentTimingRecorder delegate : delegates) {
-        try {
-          ProducerTimingRecorder recorder = delegate.producerTimingRecorderFor(token);
-          if (recorder != null) {
-            recordersBuilder.add(recorder);
-          }
-        } catch (RuntimeException e) {
-          logProducerTimingRecorderForException(e, delegate, token);
-        }
-      }
-      ImmutableList<ProducerTimingRecorder> recorders = recordersBuilder.build();
-      switch (recorders.size()) {
-        case 0:
-          return ProducerTimingRecorder.noOp();
-        case 1:
-          return new NonThrowingProducerTimingRecorder(Iterables.getOnlyElement(recorders));
-        default:
-          return new DelegatingProducerTimingRecorder(recorders);
-      }
-    }
-
-    static final class Factory implements ProductionComponentTimingRecorder.Factory {
-      private final ImmutableList<? extends ProductionComponentTimingRecorder.Factory> delegates;
-
-      Factory(Iterable<? extends ProductionComponentTimingRecorder.Factory> delegates) {
-        this.delegates = ImmutableList.copyOf(delegates);
-      }
-
-      @Override
-      public ProductionComponentTimingRecorder create(Object component) {
-        ImmutableList.Builder<ProductionComponentTimingRecorder> recordersBuilder =
-            ImmutableList.builder();
-        for (ProductionComponentTimingRecorder.Factory delegate : delegates) {
-          try {
-            ProductionComponentTimingRecorder recorder = delegate.create(component);
-            if (recorder != null) {
-              recordersBuilder.add(recorder);
-            }
-          } catch (RuntimeException e) {
-            logCreateException(e, delegate, component);
-          }
-        }
-        ImmutableList<ProductionComponentTimingRecorder> recorders = recordersBuilder.build();
-        switch (recorders.size()) {
-          case 0:
-            return noOpProductionComponentTimingRecorder();
-          case 1:
-            return new NonThrowingProductionComponentTimingRecorder(
-                Iterables.getOnlyElement(recorders));
-          default:
-            return new DelegatingProductionComponentTimingRecorder(recorders);
-        }
-      }
-    }
-  }
-
-  /**
-   * A producer recorder that delegates to several recorders, and catches and logs all exceptions
-   * that the delegates throw.
-   */
-  private static final class DelegatingProducerTimingRecorder extends ProducerTimingRecorder {
-    private final ImmutableList<ProducerTimingRecorder> delegates;
-
-    DelegatingProducerTimingRecorder(ImmutableList<ProducerTimingRecorder> delegates) {
-      this.delegates = delegates;
-    }
-
-    @Override
-    public void recordMethod(long startedNanos, long durationNanos) {
-      for (ProducerTimingRecorder delegate : delegates) {
-        try {
-          delegate.recordMethod(startedNanos, durationNanos);
-        } catch (RuntimeException e) {
-          logProducerTimingRecorderMethodException(e, delegate, "recordMethod");
-        }
-      }
-    }
-
-    @Override
-    public void recordSuccess(long latencyNanos) {
-      for (ProducerTimingRecorder delegate : delegates) {
-        try {
-          delegate.recordSuccess(latencyNanos);
-        } catch (RuntimeException e) {
-          logProducerTimingRecorderMethodException(e, delegate, "recordSuccess");
-        }
-      }
-    }
-
-    @Override
-    public void recordFailure(Throwable exception, long latencyNanos) {
-      for (ProducerTimingRecorder delegate : delegates) {
-        try {
-          delegate.recordFailure(exception, latencyNanos);
-        } catch (RuntimeException e) {
-          logProducerTimingRecorderMethodException(e, delegate, "recordFailure");
-        }
-      }
-    }
-
-    @Override
-    public void recordSkip(Throwable exception) {
-      for (ProducerTimingRecorder delegate : delegates) {
-        try {
-          delegate.recordSkip(exception);
-        } catch (RuntimeException e) {
-          logProducerTimingRecorderMethodException(e, delegate, "recordSkip");
-        }
-      }
-    }
-  }
-
-  /** Returns a recorder factory that returns no-op component recorders. */
-  public static ProductionComponentTimingRecorder.Factory
-      noOpProductionComponentTimingRecorderFactory() {
-    return NO_OP_PRODUCTION_COMPONENT_TIMING_RECORDER_FACTORY;
-  }
-
-  /** Returns a component recorder that returns no-op producer recorders. */
-  public static ProductionComponentTimingRecorder noOpProductionComponentTimingRecorder() {
-    return NO_OP_PRODUCTION_COMPONENT_TIMING_RECORDER;
-  }
-
-  private static final ProductionComponentTimingRecorder.Factory
-      NO_OP_PRODUCTION_COMPONENT_TIMING_RECORDER_FACTORY =
-          new ProductionComponentTimingRecorder.Factory() {
-            @Override
-            public ProductionComponentTimingRecorder create(Object component) {
-              return noOpProductionComponentTimingRecorder();
-            }
-          };
-
-  private static final ProductionComponentTimingRecorder
-      NO_OP_PRODUCTION_COMPONENT_TIMING_RECORDER =
-          new ProductionComponentTimingRecorder() {
-            @Override
-            public ProducerTimingRecorder producerTimingRecorderFor(ProducerToken token) {
-              return ProducerTimingRecorder.noOp();
-            }
-          };
-
-  private static void logCreateException(
-      RuntimeException e, ProductionComponentTimingRecorder.Factory factory, Object component) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProductionComponentTimingRecorder.Factory.create on"
-            + " factory "
-            + factory
-            + " with component "
-            + component,
-        e);
-  }
-
-  private static void logProducerTimingRecorderForException(
-      RuntimeException e, ProductionComponentTimingRecorder recorder, ProducerToken token) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProductionComponentTimingRecorder.producerTimingRecorderFor"
-            + "on recorder "
-            + recorder
-            + " with token "
-            + token,
-        e);
-  }
-
-  private static void logProducerTimingRecorderMethodException(
-      RuntimeException e, ProducerTimingRecorder recorder, String method) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProducerTimingRecorder."
-            + method
-            + " on recorder "
-            + recorder,
-        e);
-  }
-
-  private TimingRecorders() {}
-}
diff --git a/java/dagger/producers/monitoring/internal/Monitors.java b/java/dagger/producers/monitoring/internal/Monitors.java
deleted file mode 100644
index 13b438a..0000000
--- a/java/dagger/producers/monitoring/internal/Monitors.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring.internal;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.Collection;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.inject.Provider;
-
-/**
- * Utility methods relating to monitoring, for use in generated producers code.
- */
-public final class Monitors {
-  private static final Logger logger = Logger.getLogger(Monitors.class.getName());
-
-  /**
-   * Returns a monitor factory that delegates to the given factories, and ensures that any method
-   * called on this object, even transitively, does not throw a {@link RuntimeException} or return
-   * null.
-   *
-   * <p>If the delegate monitors throw an {@link Error}, then that will escape this monitor
-   * implementation. Errors are treated as unrecoverable conditions, and may cause the entire
-   * component's execution to fail.
-   */
-  public static ProductionComponentMonitor.Factory delegatingProductionComponentMonitorFactory(
-      Collection<? extends ProductionComponentMonitor.Factory> factories) {
-    if (factories.isEmpty()) {
-      return ProductionComponentMonitor.Factory.noOp();
-    } else if (factories.size() == 1) {
-      return new NonThrowingProductionComponentMonitor.Factory(Iterables.getOnlyElement(factories));
-    } else {
-      return new DelegatingProductionComponentMonitor.Factory(factories);
-    }
-  }
-
-  /**
-   * Creates a new monitor for the given component, from a set of monitor factories. This will not
-   * throw a {@link RuntimeException} or return null.
-   */
-  public static ProductionComponentMonitor createMonitorForComponent(
-      Provider<?> componentProvider,
-      Provider<Set<ProductionComponentMonitor.Factory>> monitorFactorySetProvider) {
-    try {
-      ProductionComponentMonitor.Factory factory =
-          delegatingProductionComponentMonitorFactory(monitorFactorySetProvider.get());
-      return factory.create(componentProvider.get());
-    } catch (RuntimeException e) {
-      logger.log(Level.SEVERE, "RuntimeException while constructing monitor factories.", e);
-      return ProductionComponentMonitor.noOp();
-    }
-  }
-
-  /**
-   * A component monitor that delegates to a single monitor, and catches and logs all exceptions
-   * that the delegate throws.
-   */
-  private static final class NonThrowingProductionComponentMonitor
-      extends ProductionComponentMonitor {
-    private final ProductionComponentMonitor delegate;
-
-    NonThrowingProductionComponentMonitor(ProductionComponentMonitor delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public ProducerMonitor producerMonitorFor(ProducerToken token) {
-      try {
-        ProducerMonitor monitor = delegate.producerMonitorFor(token);
-        return monitor == null ? ProducerMonitor.noOp() : new NonThrowingProducerMonitor(monitor);
-      } catch (RuntimeException e) {
-        logProducerMonitorForException(e, delegate, token);
-        return ProducerMonitor.noOp();
-      }
-    }
-
-    static final class Factory extends ProductionComponentMonitor.Factory {
-      private final ProductionComponentMonitor.Factory delegate;
-
-      Factory(ProductionComponentMonitor.Factory delegate) {
-        this.delegate = delegate;
-      }
-
-      @Override
-      public ProductionComponentMonitor create(Object component) {
-        try {
-          ProductionComponentMonitor monitor = delegate.create(component);
-          return monitor == null
-              ? ProductionComponentMonitor.noOp()
-              : new NonThrowingProductionComponentMonitor(monitor);
-        } catch (RuntimeException e) {
-          logCreateException(e, delegate, component);
-          return ProductionComponentMonitor.noOp();
-        }
-      }
-    }
-  }
-
-  /**
-   * A producer monitor that delegates to a single monitor, and catches and logs all exceptions
-   * that the delegate throws.
-   */
-  private static final class NonThrowingProducerMonitor extends ProducerMonitor {
-    private final ProducerMonitor delegate;
-
-    NonThrowingProducerMonitor(ProducerMonitor delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public void requested() {
-      try {
-        delegate.requested();
-      } catch (RuntimeException e) {
-        logProducerMonitorMethodException(e, delegate, "requested");
-      }
-    }
-
-    @Override
-    public void ready() {
-      try {
-        delegate.ready();
-      } catch (RuntimeException e) {
-        logProducerMonitorMethodException(e, delegate, "ready");
-      }
-    }
-
-    @Override
-    public void methodStarting() {
-      try {
-        delegate.methodStarting();
-      } catch (RuntimeException e) {
-        logProducerMonitorMethodException(e, delegate, "methodStarting");
-      }
-    }
-
-    @Override
-    public void methodFinished() {
-      try {
-        delegate.methodFinished();
-      } catch (RuntimeException e) {
-        logProducerMonitorMethodException(e, delegate, "methodFinished");
-      }
-    }
-
-    @Override
-    public void succeeded(Object o) {
-      try {
-        delegate.succeeded(o);
-      } catch (RuntimeException e) {
-        logProducerMonitorArgMethodException(e, delegate, "succeeded", o);
-      }
-    }
-
-    @Override
-    public void failed(Throwable t) {
-      try {
-        delegate.failed(t);
-      } catch (RuntimeException e) {
-        logProducerMonitorArgMethodException(e, delegate, "failed", t);
-      }
-    }
-  }
-
-  /**
-   * A component monitor that delegates to several monitors, and catches and logs all exceptions
-   * that the delegates throw.
-   */
-  private static final class DelegatingProductionComponentMonitor
-      extends ProductionComponentMonitor {
-    private final ImmutableList<ProductionComponentMonitor> delegates;
-
-    DelegatingProductionComponentMonitor(ImmutableList<ProductionComponentMonitor> delegates) {
-      this.delegates = delegates;
-    }
-
-    @Override
-    public ProducerMonitor producerMonitorFor(ProducerToken token) {
-      ImmutableList.Builder<ProducerMonitor> monitorsBuilder = ImmutableList.builder();
-      for (ProductionComponentMonitor delegate : delegates) {
-        try {
-          ProducerMonitor monitor = delegate.producerMonitorFor(token);
-          if (monitor != null) {
-            monitorsBuilder.add(monitor);
-          }
-        } catch (RuntimeException e) {
-          logProducerMonitorForException(e, delegate, token);
-        }
-      }
-      ImmutableList<ProducerMonitor> monitors = monitorsBuilder.build();
-      if (monitors.isEmpty()) {
-        return ProducerMonitor.noOp();
-      } else if (monitors.size() == 1) {
-        return new NonThrowingProducerMonitor(Iterables.getOnlyElement(monitors));
-      } else {
-        return new DelegatingProducerMonitor(monitors);
-      }
-    }
-
-    static final class Factory extends ProductionComponentMonitor.Factory {
-      private final ImmutableList<? extends ProductionComponentMonitor.Factory> delegates;
-
-      Factory(Iterable<? extends ProductionComponentMonitor.Factory> delegates) {
-        this.delegates = ImmutableList.copyOf(delegates);
-      }
-
-      @Override
-      public ProductionComponentMonitor create(Object component) {
-        ImmutableList.Builder<ProductionComponentMonitor> monitorsBuilder = ImmutableList.builder();
-        for (ProductionComponentMonitor.Factory delegate : delegates) {
-          try {
-            ProductionComponentMonitor monitor = delegate.create(component);
-            if (monitor != null) {
-              monitorsBuilder.add(monitor);
-            }
-          } catch (RuntimeException e) {
-            logCreateException(e, delegate, component);
-          }
-        }
-        ImmutableList<ProductionComponentMonitor> monitors = monitorsBuilder.build();
-        if (monitors.isEmpty()) {
-          return ProductionComponentMonitor.noOp();
-        } else if (monitors.size() == 1) {
-          return new NonThrowingProductionComponentMonitor(Iterables.getOnlyElement(monitors));
-        } else {
-          return new DelegatingProductionComponentMonitor(monitors);
-        }
-      }
-    }
-  }
-
-  /**
-   * A producer monitor that delegates to several monitors, and catches and logs all exceptions
-   * that the delegates throw.
-   */
-  private static final class DelegatingProducerMonitor extends ProducerMonitor {
-    private final ImmutableList<ProducerMonitor> delegates;
-
-    DelegatingProducerMonitor(ImmutableList<ProducerMonitor> delegates) {
-      this.delegates = delegates;
-    }
-
-    @Override
-    public void requested() {
-      for (ProducerMonitor delegate : delegates) {
-        try {
-          delegate.requested();
-        } catch (RuntimeException e) {
-          logProducerMonitorMethodException(e, delegate, "requested");
-        }
-      }
-    }
-
-    @Override
-    public void ready() {
-      for (ProducerMonitor delegate : delegates) {
-        try {
-          delegate.ready();
-        } catch (RuntimeException e) {
-          logProducerMonitorMethodException(e, delegate, "ready");
-        }
-      }
-    }
-
-    @Override
-    public void methodStarting() {
-      for (ProducerMonitor delegate : delegates) {
-        try {
-          delegate.methodStarting();
-        } catch (RuntimeException e) {
-          logProducerMonitorMethodException(e, delegate, "methodStarting");
-        }
-      }
-    }
-
-    @Override
-    public void methodFinished() {
-      for (ProducerMonitor delegate : delegates.reverse()) {
-        try {
-          delegate.methodFinished();
-        } catch (RuntimeException e) {
-          logProducerMonitorMethodException(e, delegate, "methodFinished");
-        }
-      }
-    }
-
-    @Override
-    public void succeeded(Object o) {
-      for (ProducerMonitor delegate : delegates.reverse()) {
-        try {
-          delegate.succeeded(o);
-        } catch (RuntimeException e) {
-          logProducerMonitorArgMethodException(e, delegate, "succeeded", o);
-        }
-      }
-    }
-
-    @Override
-    public void failed(Throwable t) {
-      for (ProducerMonitor delegate : delegates.reverse()) {
-        try {
-          delegate.failed(t);
-        } catch (RuntimeException e) {
-          logProducerMonitorArgMethodException(e, delegate, "failed", t);
-        }
-      }
-    }
-  }
-
-  /** Returns a provider of a no-op component monitor. */
-  public static Provider<ProductionComponentMonitor> noOpProductionComponentMonitorProvider() {
-    return NO_OP_PRODUCTION_COMPONENT_MONITOR_PROVIDER;
-  }
-
-  private static final Provider<ProductionComponentMonitor>
-      NO_OP_PRODUCTION_COMPONENT_MONITOR_PROVIDER =
-          new Provider<ProductionComponentMonitor>() {
-            @Override
-            public ProductionComponentMonitor get() {
-              return ProductionComponentMonitor.noOp();
-            }
-          };
-
-  private static void logCreateException(
-      RuntimeException e, ProductionComponentMonitor.Factory factory, Object component) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProductionComponentMonitor.Factory.create on factory "
-            + factory
-            + " with component "
-            + component,
-        e);
-  }
-
-  private static void logProducerMonitorForException(
-      RuntimeException e, ProductionComponentMonitor monitor, ProducerToken token) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProductionComponentMonitor.producerMonitorFor on monitor "
-            + monitor
-            + " with token "
-            + token,
-        e);
-  }
-
-  private static void logProducerMonitorMethodException(
-      RuntimeException e, ProducerMonitor monitor, String method) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProducerMonitor." + method + " on monitor " + monitor,
-        e);
-  }
-
-  private static void logProducerMonitorArgMethodException(
-      RuntimeException e, ProducerMonitor monitor, String method, Object arg) {
-    logger.log(
-        Level.SEVERE,
-        "RuntimeException while calling ProducerMonitor."
-            + method
-            + " on monitor "
-            + monitor
-            + " with "
-            + arg,
-        e);
-  }
-
-  private Monitors() {}
-}
diff --git a/java/dagger/producers/monitoring/package-info.java b/java/dagger/producers/monitoring/package-info.java
deleted file mode 100644
index 122df5d..0000000
--- a/java/dagger/producers/monitoring/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-/**
- * This package provides hooks for monitoring producers.
- *
- * <p>The interfaces in this package are not stable. Do not use these interfaces unless you are
- * prepared to be broken.
- */
-
-package dagger.producers.monitoring;
diff --git a/java/dagger/producers/package-info.java b/java/dagger/producers/package-info.java
deleted file mode 100644
index 9693ae9..0000000
--- a/java/dagger/producers/package-info.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-/**
- * This package contains the public API for Dagger 2's producer functionality.
- *
- * <p>Dagger Producers is an extension to Dagger that implements asynchronous dependency injection
- * in Java.
- *
- * <p>Extended documentation on Dagger Producers can be found at <a
- * href="https://dagger.dev/producers">https://dagger.dev/producers</a>.
- */
-package dagger.producers;
diff --git a/java/dagger/spi/BUILD b/java/dagger/spi/BUILD
deleted file mode 100644
index 9c04582..0000000
--- a/java/dagger/spi/BUILD
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018 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.
-
-# Description:
-#   The Service Provider Interface for Dagger's binding graph model
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-
-filegroup(
-    name = "spi-srcs",
-    srcs = glob(["*.java"]),
-)
-
-load("//tools:maven.bzl", "POM_VERSION", "pom_file")
-
-java_library(
-    name = "spi",
-    srcs = [":spi-srcs"],
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    tags = ["maven_coordinates=com.google.dagger:dagger-spi:" + POM_VERSION],
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/model",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/error_prone:annotations",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
-
-pom_file(
-    name = "pom",
-    artifact_id = "dagger-spi",
-    artifact_name = "Dagger SPI",
-    targets = [
-        "//java/dagger/model",
-        ":spi",
-    ],
-)
diff --git a/java/dagger/spi/BindingGraphPlugin.java b/java/dagger/spi/BindingGraphPlugin.java
deleted file mode 100644
index 02a051b..0000000
--- a/java/dagger/spi/BindingGraphPlugin.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 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.spi;
-
-import dagger.model.BindingGraph;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-
-/**
- * A pluggable visitor for {@link BindingGraph}.
- *
- * <p>Note: This is still experimental and will change.
- */
-public interface BindingGraphPlugin {
-  /**
-   * Called once for each valid root binding graph encountered by the Dagger processor. May report
-   * diagnostics using {@code diagnosticReporter}.
-   */
-  void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter);
-
-  /**
-   * Initializes this plugin with a {@link Filer} that it can use to write Java or other files based
-   * on the binding graph. This will be called once per instance of this plugin, before any graph is
-   * {@linkplain #visitGraph(BindingGraph, DiagnosticReporter) visited}.
-   *
-   * @see javax.annotation.processing.ProcessingEnvironment#getFiler()
-   */
-  default void initFiler(Filer filer) {}
-
-  /**
-   * Initializes this plugin with a {@link Types} instance. This will be called once per instance of
-   * this plugin, before any graph is {@linkplain #visitGraph(BindingGraph, DiagnosticReporter)
-   * visited}.
-   *
-   * @see javax.annotation.processing.ProcessingEnvironment#getTypeUtils()
-   */
-  default void initTypes(Types types) {}
-
-  /**
-   * Initializes this plugin with a {@link Elements} instance. This will be called once per instance
-   * of this plugin, before any graph is {@linkplain #visitGraph(BindingGraph, DiagnosticReporter)
-   * visited}.
-   *
-   * @see javax.annotation.processing.ProcessingEnvironment#getElementUtils()
-   */
-  default void initElements(Elements elements) {}
-
-  /**
-   * Initializes this plugin with a filtered view of the options passed on the {@code javac}
-   * command-line for all keys from {@link #supportedOptions()}. This will be called once per
-   * instance of this plugin, before any graph is {@linkplain #visitGraph(BindingGraph,
-   * DiagnosticReporter) visited}.
-   *
-   * @see javax.annotation.processing.ProcessingEnvironment#getOptions()
-   */
-  default void initOptions(Map<String, String> options) {}
-
-  /**
-   * Returns the annotation-processing options that this plugin uses to configure behavior.
-   *
-   * @see javax.annotation.processing.Processor#getSupportedOptions()
-   */
-  default Set<String> supportedOptions() {
-    return Collections.emptySet();
-  }
-
-  /**
-   * A distinguishing name of the plugin that will be used in diagnostics printed to the {@link
-   * Messager}. By default, the {@linkplain Class#getCanonicalName() fully qualified name} of the
-   * plugin is used.
-   */
-  default String pluginName() {
-    return getClass().getCanonicalName();
-  }
-}
diff --git a/java/dagger/spi/DiagnosticReporter.java b/java/dagger/spi/DiagnosticReporter.java
deleted file mode 100644
index f9ec41e..0000000
--- a/java/dagger/spi/DiagnosticReporter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2018 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.spi;
-
-import com.google.errorprone.annotations.FormatMethod;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ChildFactoryMethodEdge;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.model.BindingGraph.DependencyEdge;
-import dagger.model.BindingGraph.MaybeBinding;
-import javax.tools.Diagnostic;
-
-/**
- * An object that {@link BindingGraphPlugin}s can use to report diagnostics while visiting a {@link
- * BindingGraph}.
- *
- * <p>Note: This API is still experimental and will change.
- */
-public interface DiagnosticReporter {
-  /**
-   * Reports a diagnostic for a component. For non-root components, includes information about the
-   * path from the root component.
-   */
-  void reportComponent(Diagnostic.Kind diagnosticKind, ComponentNode componentNode, String message);
-
-  /**
-   * Reports a diagnostic for a component. For non-root components, includes information about the
-   * path from the root component.
-   */
-  @FormatMethod
-  void reportComponent(
-      Diagnostic.Kind diagnosticKind,
-      ComponentNode componentNode,
-      String messageFormat,
-      Object firstArg,
-      Object... moreArgs);
-
-  /**
-   * Reports a diagnostic for a binding or missing binding. Includes information about how the
-   * binding is reachable from entry points.
-   */
-  void reportBinding(Diagnostic.Kind diagnosticKind, MaybeBinding binding, String message);
-
-  /**
-   * Reports a diagnostic for a binding or missing binding. Includes information about how the
-   * binding is reachable from entry points.
-   */
-  @FormatMethod
-  void reportBinding(
-      Diagnostic.Kind diagnosticKind,
-      MaybeBinding binding,
-      String messageFormat,
-      Object firstArg,
-      Object... moreArgs);
-
-  /**
-   * Reports a diagnostic for a dependency. Includes information about how the dependency is
-   * reachable from entry points.
-   */
-  void reportDependency(
-      Diagnostic.Kind diagnosticKind, DependencyEdge dependencyEdge, String message);
-
-  /**
-   * Reports a diagnostic for a dependency. Includes information about how the dependency is
-   * reachable from entry points.
-   */
-  @FormatMethod
-  void reportDependency(
-      Diagnostic.Kind diagnosticKind,
-      DependencyEdge dependencyEdge,
-      String messageFormat,
-      Object firstArg,
-      Object... moreArgs);
-
-  /** Reports a diagnostic for a subcomponent factory method. */
-  void reportSubcomponentFactoryMethod(
-      Diagnostic.Kind diagnosticKind,
-      ChildFactoryMethodEdge childFactoryMethodEdge,
-      String message);
-
-  /** Reports a diagnostic for a subcomponent factory method. */
-  @FormatMethod
-  void reportSubcomponentFactoryMethod(
-      Diagnostic.Kind diagnosticKind,
-      ChildFactoryMethodEdge childFactoryMethodEdge,
-      String messageFormat,
-      Object firstArg,
-      Object... moreArgs);
-}
diff --git a/java/dagger/spi/package-info.java b/java/dagger/spi/package-info.java
deleted file mode 100644
index 87ebb33..0000000
--- a/java/dagger/spi/package-info.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-/**
- * This package contains the Service Provider interface (SPI) to the {@link dagger.model} APIs at
- * annotation-processing-time.
- *
- * <p>This package is experimental, and APIs may change at over time.
- */
-@CheckReturnValue
-@Beta
-package dagger.spi;
-
-import com.google.errorprone.annotations.CheckReturnValue;
-import dagger.internal.Beta;
diff --git a/javatests/dagger/BUILD b/javatests/dagger/BUILD
deleted file mode 100644
index 3debec5..0000000
--- a/javatests/dagger/BUILD
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   A JSR-330 compliant dependency injection system for android and java
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "core_tests",
-    srcs = glob(["**/*.java"]),
-    functional = 0,
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = [
-        "//java/dagger:core",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/android/AndroidInjectionTest.java b/javatests/dagger/android/AndroidInjectionTest.java
deleted file mode 100644
index 19b6e84..0000000
--- a/javatests/dagger/android/AndroidInjectionTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2016 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.android;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.Fragment;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.util.FragmentTestUtil;
-
-@Config(manifest = Config.NONE)
-@RunWith(RobolectricTestRunner.class)
-public final class AndroidInjectionTest {
-
-  // Most positive tests are performed in javatests/dagger/android/support/functional, but
-  // Robolectric's support for framework fragments is lacking, so we supplement those tests here:
-  public static class InjectableFragment extends Fragment {
-    String tag;
-  }
-
-  private static AndroidInjector<Fragment> fakeFragmentInjector(String tag) {
-    return instance -> {
-      if (instance instanceof InjectableFragment) {
-        ((InjectableFragment) instance).tag = tag;
-      }
-    };
-  }
-
-  public static class ApplicationInjectsFragment extends Application
-      implements HasFragmentInjector {
-    @Override
-    public AndroidInjector<Fragment> fragmentInjector() {
-      return fakeFragmentInjector("injected by app");
-    }
-  }
-
-  @Config(manifest = Config.NONE, application = ApplicationInjectsFragment.class)
-  @Test
-  public void fragmentInjectedByApplication() {
-    Activity activity = Robolectric.setupActivity(Activity.class);
-    InjectableFragment fragment = new InjectableFragment();
-    activity.getFragmentManager().beginTransaction().add(fragment, "tag").commit();
-
-    AndroidInjection.inject(fragment);
-
-    assertThat(fragment.tag).isEqualTo("injected by app");
-  }
-
-  public static class ActivityInjectsFragment extends Activity implements HasFragmentInjector {
-    @Override
-    public AndroidInjector<Fragment> fragmentInjector() {
-      return fakeFragmentInjector("injected by activity");
-    }
-  }
-
-  @Config(manifest = Config.NONE, application = ApplicationInjectsFragment.class)
-  @Test
-  public void fragmentInjectedByActivity() {
-    ActivityInjectsFragment activity = Robolectric.setupActivity(ActivityInjectsFragment.class);
-    InjectableFragment fragment = new InjectableFragment();
-    activity.getFragmentManager().beginTransaction().add(fragment, "tag").commit();
-
-    AndroidInjection.inject(fragment);
-
-    assertThat(fragment.tag).isEqualTo("injected by activity");
-  }
-
-  public static class ParentFragmentInjectsChildFragment extends Fragment
-      implements HasFragmentInjector {
-    @Override
-    public AndroidInjector<Fragment> fragmentInjector() {
-      return fakeFragmentInjector("injected by parent fragment");
-    }
-  }
-
-  @Config(manifest = Config.NONE, application = ApplicationInjectsFragment.class)
-  @Test
-  public void fragmentInjectedByParentFragment() {
-    ActivityInjectsFragment activity = Robolectric.setupActivity(ActivityInjectsFragment.class);
-    ParentFragmentInjectsChildFragment parentFragment = new ParentFragmentInjectsChildFragment();
-    InjectableFragment childFragment = new InjectableFragment();
-
-    activity.getFragmentManager().beginTransaction().add(parentFragment, "tag").commit();
-    parentFragment
-        .getChildFragmentManager()
-        .beginTransaction()
-        .add(childFragment, "child-tag")
-        .commit();
-    AndroidInjection.inject(childFragment);
-
-    assertThat(childFragment.tag).isEqualTo("injected by parent fragment");
-  }
-
-  @Test
-  public void injectActivity_applicationDoesntImplementHasActivityInjector() {
-    Activity activity = Robolectric.setupActivity(Activity.class);
-
-    try {
-      AndroidInjection.inject(activity);
-      fail();
-    } catch (Exception e) {
-      assertThat(e)
-          .hasMessageThat()
-          .contains("Application does not implement dagger.android.HasAndroidInjector");
-    }
-  }
-
-  @Test
-  public void injectFragment_hasFragmentInjectorNotFound() {
-    Fragment fragment = new Fragment();
-    FragmentTestUtil.startFragment(fragment);
-
-    try {
-      AndroidInjection.inject(fragment);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).hasMessageThat().contains("No injector was found");
-    }
-  }
-
-  private static class ApplicationReturnsNull extends Application
-      implements HasActivityInjector, HasFragmentInjector {
-    @Override
-    public AndroidInjector<Activity> activityInjector() {
-      return null;
-    }
-
-    @Override
-    public AndroidInjector<Fragment> fragmentInjector() {
-      return null;
-    }
-  }
-
-  @Test
-  @Config(manifest = Config.NONE, application = ApplicationReturnsNull.class)
-  public void activityInjector_returnsNull() {
-    Activity activity = Robolectric.setupActivity(Activity.class);
-
-    try {
-      AndroidInjection.inject(activity);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).hasMessageThat().contains("activityInjector() returned null");
-    }
-  }
-
-  @Test
-  @Config(manifest = Config.NONE, application = ApplicationReturnsNull.class)
-  public void fragmentInjector_returnsNull() {
-    Fragment fragment = new Fragment();
-    FragmentTestUtil.startFragment(fragment);
-
-    try {
-      AndroidInjection.inject(fragment);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).hasMessageThat().contains("fragmentInjector() returned null");
-    }
-  }
-
-  @Test
-  public void injectActivity_nullInput() {
-    try {
-      AndroidInjection.inject((Activity) null);
-      fail();
-    } catch (NullPointerException e) {
-      assertThat(e).hasMessageThat().contains("activity");
-    }
-  }
-
-  @Test
-  public void injectFragment_nullInput() {
-    try {
-      AndroidInjection.inject((Fragment) null);
-      fail();
-    } catch (NullPointerException e) {
-      assertThat(e).hasMessageThat().contains("fragment");
-    }
-  }
-}
diff --git a/javatests/dagger/android/BUILD b/javatests/dagger/android/BUILD
deleted file mode 100644
index 5bc3f45..0000000
--- a/javatests/dagger/android/BUILD
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   Tests for Dagger's Android integrations
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenRobolectricTests")
-
-GenRobolectricTests(
-    name = "android_tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    manifest_values = {"minSdkVersion": "17"},
-    deps = [
-        "//:dagger_with_compiler",
-        "//java/dagger/android",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/android/DispatchingAndroidInjectorTest.java b/javatests/dagger/android/DispatchingAndroidInjectorTest.java
deleted file mode 100644
index d0306b8..0000000
--- a/javatests/dagger/android/DispatchingAndroidInjectorTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2017 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.android;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import android.app.Activity;
-import com.google.common.collect.ImmutableMap;
-import dagger.android.AndroidInjector.Factory;
-import dagger.android.DispatchingAndroidInjector.InvalidInjectorBindingException;
-import java.util.Map;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-@Config(manifest = Config.NONE)
-@RunWith(RobolectricTestRunner.class)
-public final class DispatchingAndroidInjectorTest {
-  @Test
-  public void withClassKeys() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(
-            ImmutableMap.of(FooActivity.class, FooInjector.Factory::new), ImmutableMap.of());
-
-    FooActivity activity = Robolectric.setupActivity(FooActivity.class);
-    assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue();
-  }
-
-  @Test
-  public void withStringKeys() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(
-            ImmutableMap.of(),
-            ImmutableMap.of(FooActivity.class.getName(), FooInjector.Factory::new));
-
-    FooActivity activity = Robolectric.setupActivity(FooActivity.class);
-    assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue();
-  }
-
-  @Test
-  public void withMixedKeys() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(
-            ImmutableMap.of(FooActivity.class, FooInjector.Factory::new),
-            ImmutableMap.of(BarActivity.class.getName(), BarInjector.Factory::new));
-
-    FooActivity fooActivity = Robolectric.setupActivity(FooActivity.class);
-    assertThat(dispatchingAndroidInjector.maybeInject(fooActivity)).isTrue();
-    BarActivity barActivity = Robolectric.setupActivity(BarActivity.class);
-    assertThat(dispatchingAndroidInjector.maybeInject(barActivity)).isTrue();
-  }
-
-  @Test
-  public void maybeInject_returnsFalse_ifNoMatchingInjectorExists() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(ImmutableMap.of(), ImmutableMap.of());
-
-    BarActivity activity = Robolectric.setupActivity(BarActivity.class);
-    assertThat(dispatchingAndroidInjector.maybeInject(activity)).isFalse();
-  }
-
-  @Test
-  public void throwsIfFactoryCreateReturnsNull() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(
-            ImmutableMap.of(FooActivity.class, () -> null), ImmutableMap.of());
-    FooActivity activity = Robolectric.setupActivity(FooActivity.class);
-
-    try {
-      dispatchingAndroidInjector.maybeInject(activity);
-      fail("Expected NullPointerException");
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test
-  public void throwsIfClassMismatched() {
-    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector =
-        newDispatchingAndroidInjector(
-            ImmutableMap.of(FooActivity.class, BarInjector.Factory::new), ImmutableMap.of());
-    FooActivity activity = Robolectric.setupActivity(FooActivity.class);
-
-    try {
-      dispatchingAndroidInjector.maybeInject(activity);
-      fail("Expected InvalidInjectorBindingException");
-    } catch (InvalidInjectorBindingException expected) {
-    }
-  }
-
-  private static <T> DispatchingAndroidInjector<T> newDispatchingAndroidInjector(
-      Map<Class<?>, Provider<Factory<?>>> injectorFactoriesWithClassKeys,
-      Map<String, Provider<AndroidInjector.Factory<?>>>
-          injectorFactoriesWithStringKeys) {
-    return new DispatchingAndroidInjector<>(
-        injectorFactoriesWithClassKeys,
-        injectorFactoriesWithStringKeys ,
-        ImmutableMap.of(),
-        ImmutableMap.of());
-  }
-
-  static class FooActivity extends Activity {}
-
-  static class BarActivity extends Activity {}
-
-  static class FooInjector implements AndroidInjector<FooActivity> {
-    @Override
-    public void inject(FooActivity instance) {}
-
-    static class Factory implements AndroidInjector.Factory<FooActivity> {
-      @Override
-      public AndroidInjector<FooActivity> create(FooActivity activity) {
-        return new FooInjector();
-      }
-    }
-  }
-
-  static class BarInjector implements AndroidInjector<BarActivity> {
-    @Override
-    public void inject(BarActivity instance) {}
-
-    static class Factory implements AndroidInjector.Factory<BarActivity> {
-      @Override
-      public AndroidInjector<BarActivity> create(BarActivity activity) {
-        return new BarInjector();
-      }
-    }
-  }
-}
diff --git a/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java b/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java
deleted file mode 100644
index cfa6e90..0000000
--- a/javatests/dagger/android/processor/AndroidMapKeyValidatorTest.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-
-import com.google.common.base.Joiner;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.internal.codegen.ComponentProcessor;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class AndroidMapKeyValidatorTest {
-  private static final JavaFileObject FOO_ACTIVITY =
-      JavaFileObjects.forSourceLines(
-          "test.FooActivity",
-          "package test;",
-          "",
-          "import android.app.Activity;",
-          "import dagger.android.AndroidInjector;",
-          "",
-          "public class FooActivity extends Activity {",
-          "  interface Factory extends AndroidInjector.Factory<FooActivity> {}",
-          "  abstract static class Builder extends AndroidInjector.Builder<FooActivity> {}",
-          "}");
-  private static final JavaFileObject BAR_ACTIVITY =
-      JavaFileObjects.forSourceLines(
-          "test.BarActivity",
-          "package test;",
-          "",
-          "import android.app.Activity;",
-          "",
-          "public class BarActivity extends Activity {}");
-
-  private static JavaFileObject moduleWithMethod(String... lines) {
-    return JavaFileObjects.forSourceLines(
-        "test.AndroidModule",
-        "package test;",
-        "",
-        "import android.app.Activity;",
-        "import android.app.Fragment;",
-        "import dagger.Module;",
-        "import dagger.*;",
-        "import dagger.android.*;",
-        "import dagger.multibindings.*;",
-        "import javax.inject.*;",
-        "",
-        "@Module",
-        "abstract class AndroidModule {",
-        "  " + Joiner.on("\n  ").join(lines),
-        "}");
-  }
-
-  // TODO(dpb): Change these tests to use onLineContaining() instead of onLine().
-  private static final int LINES_BEFORE_METHOD = 12;
-
-  @Test
-  public void rawFactoryType() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Factory bindRawFactory(FooActivity.Factory factory);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "should bind dagger.android.AndroidInjector.Factory<?>, "
-                + "not dagger.android.AndroidInjector.Factory");
-  }
-
-  @Test
-  public void rawBuilderType() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Builder bindRawBuilder(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "should bind dagger.android.AndroidInjector.Factory<?>, "
-                + "not dagger.android.AndroidInjector.Builder");
-  }
-
-  @Test
-  public void bindsToBuilderNotFactory() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Builder<?> bindBuilder(",
-            "    FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "should bind dagger.android.AndroidInjector.Factory<?>, not "
-                + "dagger.android.AndroidInjector.Builder<?>");
-  }
-
-  @Test
-  public void providesToBuilderNotFactory() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Provides",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "static AndroidInjector.Builder<?> bindBuilder(FooActivity.Builder builder) {",
-            "  return builder;",
-            "}");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "should bind dagger.android.AndroidInjector.Factory<?>, not "
-                + "dagger.android.AndroidInjector.Builder<?>");
-  }
-
-  @Test
-  public void bindsToConcreteTypeInsteadOfWildcard() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Builder<FooActivity> bindBuilder(",
-            "    FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "should bind dagger.android.AndroidInjector.Factory<?>, not "
-                + "dagger.android.AndroidInjector.Builder<test.FooActivity>");
-  }
-
-  @Test
-  public void bindsToBaseTypeInsteadOfWildcard() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Builder<Activity> bindBuilder(",
-            "    FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Binds methods' parameter type must be assignable to the return type");
-  }
-
-  @Test
-  public void bindsCorrectType() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindsCorrectType_AndroidInjectionKey() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@AndroidInjectionKey(\"test.FooActivity\")",
-            "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindsCorrectType_AndroidInjectionKey_unbounded() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@AndroidInjectionKey(\"test.FooActivity\")",
-            "abstract AndroidInjector.Factory<?> bindCorrectType(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindsWithScope() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "@Singleton",
-            "abstract AndroidInjector.Factory<?> bindWithScope(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("should not be scoped");
-  }
-
-  @Test
-  public void bindsWithScope_suppressWarnings() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@SuppressWarnings(\"dagger.android.ScopedInjectorFactory\")",
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "@Singleton",
-            "abstract AndroidInjector.Factory<?> bindWithScope(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void mismatchedMapKey_bindsFactory() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(BarActivity.class)",
-            "abstract AndroidInjector.Factory<?> mismatchedFactory(FooActivity.Factory factory);");
-    Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.FooActivity.Factory does not implement AndroidInjector<test.BarActivity>")
-        .inFile(module)
-        .onLine(LINES_BEFORE_METHOD + 3);
-  }
-
-  @Test
-  public void mismatchedMapKey_bindsBuilder() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(BarActivity.class)",
-            "abstract AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.FooActivity.Builder does not implement AndroidInjector<test.BarActivity>")
-        .inFile(module)
-        .onLine(LINES_BEFORE_METHOD + 3);
-  }
-
-  @Test
-  public void mismatchedMapKey_bindsBuilder_androidInjectionKey() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@AndroidInjectionKey(\"test.BarActivity\")",
-            "abstract AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.FooActivity.Builder does not implement AndroidInjector<test.BarActivity>")
-        .inFile(module)
-        .onLine(LINES_BEFORE_METHOD + 3);
-  }
-
-  @Test
-  public void mismatchedMapKey_providesBuilder() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Provides",
-            "@IntoMap",
-            "@ClassKey(BarActivity.class)",
-            "static AndroidInjector.Factory<?> mismatchedBuilder(FooActivity.Builder builder) {",
-            "  return builder;",
-            "}");
-    Compilation compilation = compile(module, FOO_ACTIVITY, BAR_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindsQualifier_ignoresChecks() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "@Named(\"unused\")",
-            // normally this should fail, since it is binding to a Builder not a Factory
-            "abstract AndroidInjector.Builder<?> bindsBuilderWithQualifier(",
-            "    FooActivity.Builder builder);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindToPrimitive() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@AndroidInjectionKey(\"test.FooActivity\")",
-            "abstract int bindInt(@Named(\"unused\") int otherInt);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void bindToNonFrameworkClass() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@AndroidInjectionKey(\"test.FooActivity\")",
-            "abstract Number bindInt(Integer integer);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void invalidBindsMethod() {
-    JavaFileObject module =
-        moduleWithMethod(
-            "@Binds",
-            "@IntoMap",
-            "@ClassKey(FooActivity.class)",
-            "abstract AndroidInjector.Factory<?> bindCorrectType(",
-            "    FooActivity.Builder builder, FooActivity.Builder builder2);");
-    Compilation compilation = compile(module, FOO_ACTIVITY);
-    assertThat(compilation).failed();
-  }
-
-  private Compilation compile(JavaFileObject... files) {
-    return javac().withProcessors(new ComponentProcessor(), new AndroidProcessor()).compile(files);
-  }
-}
diff --git a/javatests/dagger/android/processor/AndroidProcessorTest.java b/javatests/dagger/android/processor/AndroidProcessorTest.java
deleted file mode 100644
index 1a45bdd..0000000
--- a/javatests/dagger/android/processor/AndroidProcessorTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.common.truth.Truth8.assertThat;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class AndroidProcessorTest {
-  @Test
-  public void generatedProguardFile() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.android.AndroidInjectionKey;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class TestModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @AndroidInjectionKey(\"test.TestActivity\")",
-            "  static int i() { ",
-            "    return 1;",
-            "  }",
-            "}");
-    Compilation enabled =
-        javac()
-            .withProcessors(new AndroidProcessor())
-            .withOptions("-Adagger.android.experimentalUseStringKeys=true")
-            .compile(module);
-    assertThat(enabled).succeeded();
-    assertThat(enabled)
-        .generatedFile(CLASS_OUTPUT, "META-INF/proguard/dagger.android.AndroidInjectionKeys");
-
-    Compilation disabled =
-        javac()
-            .withProcessors(new AndroidProcessor())
-            .withOptions("-Adagger.android.experimentalUseStringKeys=false")
-            .compile(module);
-    assertThat(disabled).succeeded();
-    assertThat(
-            disabled.generatedFile(
-                CLASS_OUTPUT, "META-INF/proguard/dagger.android.AndroidInjectionKeys"))
-        .isEmpty();
-
-    Compilation noFlag = javac().withProcessors(new AndroidProcessor()).compile(module);
-    assertThat(noFlag).succeeded();
-    assertThat(
-            noFlag.generatedFile(
-                CLASS_OUTPUT, "META-INF/proguard/dagger.android.AndroidInjectionKeys"))
-        .isEmpty();
-  }
-}
diff --git a/javatests/dagger/android/processor/BUILD b/javatests/dagger/android/processor/BUILD
deleted file mode 100644
index 8a9c16e..0000000
--- a/javatests/dagger/android/processor/BUILD
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   Tests for Dagger's Android integrations
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "android_processor_tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "@google_bazel_common//third_party/java/guava",
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-        # TODO(ronshapiro): create a common location to define the current Android version
-        "@androidsdk//:platforms/android-26/android.jar",
-        "@google_bazel_common//third_party/java/compile_testing",
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-        "@google_bazel_common//third_party/java/truth:truth8",
-        "//java/dagger/android",
-        "//java/dagger/android/processor",
-        "//java/dagger/internal/codegen:processor",
-    ],
-)
diff --git a/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java b/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java
deleted file mode 100644
index 1718737..0000000
--- a/javatests/dagger/android/processor/ContributesAndroidInjectorTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.processor;
-
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ContributesAndroidInjectorTest {
-  private static final JavaFileObject TEST_ACTIVITY =
-      JavaFileObjects.forSourceLines(
-          "test.TestActivity",
-          "package test;",
-          "",
-          "import android.app.Activity;",
-          "",
-          "class TestActivity extends Activity {}");
-
-  @Test
-  public void notAbstract() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.android.ContributesAndroidInjector;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @ContributesAndroidInjector",
-            "  static TestActivity test() {",
-            "    return null;",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(module, TEST_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("must be abstract")
-        .inFile(module)
-        .onLineContaining("test()");
-  }
-
-  @Test
-  public void hasParameters() {
-    JavaFileObject otherActivity =
-        JavaFileObjects.forSourceLines(
-            "test.OtherActivity",
-            "package test;",
-            "",
-            "import android.app.Activity;",
-            "",
-            "class OtherActivity extends Activity {}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.android.ContributesAndroidInjector;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @ContributesAndroidInjector",
-            "  abstract TestActivity oneParam(TestActivity one);",
-            "",
-            "  @ContributesAndroidInjector",
-            "  abstract OtherActivity manyParams(OtherActivity two, Object o);",
-            "}");
-
-    Compilation compilation = compile(module, TEST_ACTIVITY, otherActivity);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cannot have parameters")
-        .inFile(module)
-        .onLineContaining("oneParam(");
-    assertThat(compilation)
-        .hadErrorContaining("cannot have parameters")
-        .inFile(module)
-        .onLineContaining("manyParams(");
-  }
-
-  @Test
-  public void notInAModule() {
-    JavaFileObject randomFile =
-        JavaFileObjects.forSourceLines(
-            "test.RandomFile",
-            "package test;",
-            "",
-            "import dagger.android.ContributesAndroidInjector;",
-            "",
-            "abstract class RandomFile {",
-            "  @ContributesAndroidInjector",
-            "  abstract TestActivity test() {}",
-            "}");
-
-    Compilation compilation = compile(randomFile, TEST_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("must be in a @Module")
-        .inFile(randomFile)
-        .onLineContaining("test()");
-  }
-
-  @Test
-  public void parameterizedReturnType() {
-    JavaFileObject parameterizedActivity =
-        JavaFileObjects.forSourceLines(
-            "test.ParameterizedActivity",
-            "package test;",
-            "",
-            "import android.app.Activity;",
-            "",
-            "class ParameterizedActivity<T> extends Activity {}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.android.ContributesAndroidInjector;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @ContributesAndroidInjector",
-            "  abstract <T> ParameterizedActivity<T> test();",
-            "}");
-
-    Compilation compilation = compile(module, TEST_ACTIVITY, parameterizedActivity);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cannot return parameterized types")
-        .inFile(module)
-        .onLineContaining("test()");
-  }
-
-  @Test
-  public void moduleIsntModule() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.android.ContributesAndroidInjector;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @ContributesAndroidInjector(modules = android.content.Intent.class)",
-            "  abstract TestActivity test();",
-            "}");
-
-    Compilation compilation = compile(module, TEST_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Intent is not a @Module")
-        .inFile(module)
-        .onLineContaining("modules = android.content.Intent.class");
-  }
-
-  @Test
-  public void hasQualifier() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.android.ContributesAndroidInjector;",
-            "import javax.inject.Qualifier;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Qualifier @interface AndroidQualifier {}",
-            "",
-            "  @AndroidQualifier",
-            "  @ContributesAndroidInjector",
-            "  abstract TestActivity test();",
-            "}");
-
-    Compilation compilation = compile(module, TEST_ACTIVITY);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@ContributesAndroidInjector methods cannot have qualifiers")
-        .inFile(module)
-        .onLineContaining("@AndroidQualifier");
-  }
-
-  private static Compilation compile(JavaFileObject... javaFileObjects) {
-    return javac().withProcessors(new AndroidProcessor()).compile(javaFileObjects);
-  }
-}
diff --git a/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java b/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java
deleted file mode 100644
index a84c7eb..0000000
--- a/javatests/dagger/android/processor/DuplicateAndroidInjectorsCheckerTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.processor;
-
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.internal.codegen.ComponentProcessor;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class DuplicateAndroidInjectorsCheckerTest {
-  @Test
-  public void conflictingMapKeys() {
-    JavaFileObject activity =
-        JavaFileObjects.forSourceLines(
-            "test.TestActivity",
-            "package test;",
-            "",
-            "import android.app.Activity;",
-            "",
-            "public class TestActivity extends Activity {}");
-    JavaFileObject injectorFactory =
-        JavaFileObjects.forSourceLines(
-            "test.TestInjectorFactory",
-            "package test;",
-            "",
-            "import dagger.android.AndroidInjector;",
-            "import javax.inject.Inject;",
-            "",
-            "class TestInjectorFactory implements AndroidInjector.Factory<TestActivity> {",
-            "  @Inject TestInjectorFactory() {}",
-            "",
-            "  @Override",
-            "  public AndroidInjector<TestActivity> create(TestActivity instance) { return null; }",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import android.app.Activity;",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.android.*;",
-            "import dagger.multibindings.*;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Binds",
-            "  @IntoMap",
-            "  @ClassKey(TestActivity.class)",
-            "  AndroidInjector.Factory<?> classKey(TestInjectorFactory factory);",
-            "",
-            "  @Binds",
-            "  @IntoMap",
-            "  @AndroidInjectionKey(\"test.TestActivity\")",
-            "  AndroidInjector.Factory<?> stringKey(TestInjectorFactory factory);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import android.app.Activity;",
-            "import dagger.Component;",
-            "import dagger.android.DispatchingAndroidInjector;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  DispatchingAndroidInjector<Activity> dispatchingInjector();",
-            "}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(ComponentProcessor.forTesting(new DuplicateAndroidInjectorsChecker()))
-            .compile(activity, injectorFactory, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Multiple injector factories bound for the same type")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-    assertThat(compilation).hadErrorContaining("classKey(test.TestInjectorFactory)");
-    assertThat(compilation).hadErrorContaining("stringKey(test.TestInjectorFactory)");
-    assertThat(compilation).hadErrorCount(1);
-  }
-}
diff --git a/javatests/dagger/android/support/AndroidSupportInjectionTest.java b/javatests/dagger/android/support/AndroidSupportInjectionTest.java
deleted file mode 100644
index 51e9992..0000000
--- a/javatests/dagger/android/support/AndroidSupportInjectionTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2016 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.android.support;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import android.app.Application;
-import android.support.v4.app.Fragment;
-import dagger.android.AndroidInjector;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.support.v4.SupportFragmentTestUtil;
-
-@Config(manifest = Config.NONE)
-@RunWith(RobolectricTestRunner.class)
-public final class AndroidSupportInjectionTest {
-  @Test
-  public void injectFragment_simpleApplication() {
-    Fragment fragment = new Fragment();
-    SupportFragmentTestUtil.startFragment(fragment);
-
-    try {
-      AndroidSupportInjection.inject(fragment);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).hasMessageThat().contains("No injector was found");
-    }
-  }
-
-  private static class ApplicationReturnsNull extends Application
-      implements HasSupportFragmentInjector {
-    @Override
-    public AndroidInjector<Fragment> supportFragmentInjector() {
-      return null;
-    }
-  }
-
-  @Test
-  @Config(manifest = Config.NONE, application = ApplicationReturnsNull.class)
-  public void fragmentInjector_returnsNull() {
-    Fragment fragment = new Fragment();
-    SupportFragmentTestUtil.startFragment(fragment);
-
-    try {
-      AndroidSupportInjection.inject(fragment);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).hasMessageThat().contains("supportFragmentInjector() returned null");
-    }
-  }
-
-  @Test
-  public void injectFragment_nullInput() {
-    try {
-      AndroidSupportInjection.inject(null);
-      fail();
-    } catch (NullPointerException e) {
-      assertThat(e).hasMessageThat().contains("fragment");
-    }
-  }
-}
diff --git a/javatests/dagger/android/support/BUILD b/javatests/dagger/android/support/BUILD
deleted file mode 100644
index 6d8f43b..0000000
--- a/javatests/dagger/android/support/BUILD
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   Tests for Dagger's Android and Support library integrations
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenRobolectricTests")
-
-GenRobolectricTests(
-    name = "android-support-tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "//:dagger_with_compiler",
-        "//java/dagger/android",
-        "//java/dagger/android/support",
-        "@androidsdk//com.android.support:appcompat-v7-25.0.0",
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/android/support/functional/AllControllersAreDirectChildrenOfApplication.java b/javatests/dagger/android/support/functional/AllControllersAreDirectChildrenOfApplication.java
deleted file mode 100644
index fa05158..0000000
--- a/javatests/dagger/android/support/functional/AllControllersAreDirectChildrenOfApplication.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.support.DaggerApplication;
-import dagger.android.support.functional.AllControllersAreDirectChildrenOfApplication.ApplicationComponent.BroadcastReceiverSubcomponent.BroadcastReceiverModule;
-import dagger.android.support.functional.AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ContentProviderSubcomponent.ContentProviderModule;
-import dagger.android.support.functional.AllControllersAreDirectChildrenOfApplication.ApplicationComponent.InnerActivitySubcomponent.InnerActivityModule;
-import dagger.android.support.functional.AllControllersAreDirectChildrenOfApplication.ApplicationComponent.IntentServiceSubcomponent.IntentServiceModule;
-import dagger.android.support.functional.AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ServiceSubcomponent.ServiceModule;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-
-public final class AllControllersAreDirectChildrenOfApplication extends DaggerApplication {
-
-  @Override
-  protected AndroidInjector<AllControllersAreDirectChildrenOfApplication> applicationInjector() {
-    return DaggerAllControllersAreDirectChildrenOfApplication_ApplicationComponent.create();
-  }
-
-  @Component(modules = {ApplicationComponent.ApplicationModule.class, AndroidInjectionModule.class})
-  interface ApplicationComponent
-      extends AndroidInjector<AllControllersAreDirectChildrenOfApplication> {
-    @Module(
-      subcomponents = {
-        ActivitySubcomponent.class,
-        InnerActivitySubcomponent.class,
-        ParentFragmentSubcomponent.class,
-        ChildFragmentSubcomponent.class,
-        DialogFragmentSubcomponent.class,
-        ServiceSubcomponent.class,
-        IntentServiceSubcomponent.class,
-        BroadcastReceiverSubcomponent.class,
-        ContentProviderSubcomponent.class
-      }
-    )
-    abstract class ApplicationModule {
-      @Provides
-      @IntoSet
-      static Class<?> addToComponentHierarchy() {
-        return ApplicationComponent.class;
-      }
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestActivity.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForTestActivity(
-          ActivitySubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(OuterClass.TestInnerClassActivity.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForInnerActivity(
-          InnerActivitySubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestParentFragment.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForParentFragment(
-          ParentFragmentSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestChildFragment.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForChildFragment(
-          ChildFragmentSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestDialogFragment.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForDialogFragment(
-          DialogFragmentSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestService.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForService(
-          ServiceSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestIntentService.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForIntentService(
-          IntentServiceSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestBroadcastReceiver.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForBroadcastReceiver(
-          BroadcastReceiverSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestContentProvider.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForContentProvider(
-          ContentProviderSubcomponent.Builder builder);
-    }
-
-    @Subcomponent(modules = ActivitySubcomponent.ActivityModule.class)
-    interface ActivitySubcomponent extends AndroidInjector<TestActivity> {
-      @Module
-      abstract class ActivityModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ActivitySubcomponent.class;
-        }
-      }
-
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestActivity> {}
-    }
-
-    @Subcomponent(modules = InnerActivityModule.class)
-    interface InnerActivitySubcomponent extends AndroidInjector<OuterClass.TestInnerClassActivity> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<OuterClass.TestInnerClassActivity> {}
-
-      @Module
-      abstract class InnerActivityModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return InnerActivitySubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = ParentFragmentSubcomponent.ParentFragmentModule.class)
-    interface ParentFragmentSubcomponent extends AndroidInjector<TestParentFragment> {
-      @Module
-      abstract class ParentFragmentModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ParentFragmentSubcomponent.class;
-        }
-      }
-
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestParentFragment> {}
-    }
-
-    @Subcomponent(modules = ChildFragmentSubcomponent.ChildFragmentModule.class)
-    interface ChildFragmentSubcomponent extends AndroidInjector<TestChildFragment> {
-      @Module
-      abstract class ChildFragmentModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ChildFragmentSubcomponent.class;
-        }
-      }
-
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestChildFragment> {}
-    }
-
-    @Subcomponent(modules = DialogFragmentSubcomponent.DialogFragmentModule.class)
-    interface DialogFragmentSubcomponent extends AndroidInjector<TestDialogFragment> {
-      @Module
-      abstract class DialogFragmentModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return DialogFragmentSubcomponent.class;
-        }
-      }
-
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestDialogFragment> {}
-    }
-
-    @Subcomponent(modules = ServiceModule.class)
-    interface ServiceSubcomponent extends AndroidInjector<TestService> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestService> {}
-
-      @Module
-      abstract class ServiceModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ServiceSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = IntentServiceModule.class)
-    interface IntentServiceSubcomponent extends AndroidInjector<TestIntentService> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestIntentService> {}
-
-      @Module
-      abstract class IntentServiceModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return IntentServiceSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = BroadcastReceiverModule.class)
-    interface BroadcastReceiverSubcomponent extends AndroidInjector<TestBroadcastReceiver> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestBroadcastReceiver> {}
-
-      @Module
-      abstract class BroadcastReceiverModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return BroadcastReceiverSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = ContentProviderModule.class)
-    interface ContentProviderSubcomponent extends AndroidInjector<TestContentProvider> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestContentProvider> {}
-
-      @Module
-      abstract class ContentProviderModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ContentProviderSubcomponent.class;
-        }
-      }
-    }
-  }
-}
diff --git a/javatests/dagger/android/support/functional/AndroidManifest.xml b/javatests/dagger/android/support/functional/AndroidManifest.xml
deleted file mode 100644
index 2e40a35..0000000
--- a/javatests/dagger/android/support/functional/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="dagger.android.support.functional">
-
-  <uses-sdk android:minSdkVersion="1" android:targetSdkVersion="26" />
-
-  <application android:theme="@style/Theme.AppCompat"
-      android:name=".UsesGeneratedModulesApplication">
-    <activity android:name="dagger.android.support.functional.ParentOfFragmentActivity"/>
-    <activity android:name="dagger.android.support.functional.SiblingOfFragmentActivity"/>
-    <activity android:name="dagger.android.support.functional.InjectedWithoutSubcomponentActivity"/>
-  </application>
-</manifest>
diff --git a/javatests/dagger/android/support/functional/BUILD b/javatests/dagger/android/support/functional/BUILD
deleted file mode 100644
index 130b971..0000000
--- a/javatests/dagger/android/support/functional/BUILD
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2017 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.
-#
-# Description:
-#   Functional test code for Dagger-Android
-
-package(default_visibility = ["//:src"])
-
-android_library(
-    name = "functional",
-    srcs = glob(
-        ["*.java"],
-        exclude = ["*Test.java"],
-    ),
-    exports_manifest = 1,
-    manifest = "AndroidManifest.xml",
-    resource_files = glob(["res/**"]),
-    deps = [
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-        "@androidsdk//com.android.support:appcompat-v7-25.0.0",
-        "@google_bazel_common//third_party/java/guava",
-        "//:dagger_with_compiler",
-        "//:android",
-        "//:android-support",
-        # TODO(ronshapiro): figure out why strict deps is failing without this
-        "@google_bazel_common//third_party/java/jsr250_annotations",
-    ],
-)
-
-load("//:test_defs.bzl", "GenRobolectricTests")
-
-GenRobolectricTests(
-    name = "functional_tests",
-    srcs = glob(["*Test.java"]),
-    deps = [
-        ":functional",
-        "//:android",
-        "//:android-support",
-        "//:dagger_with_compiler",
-        "@androidsdk//com.android.support:support-fragment-25.0.0",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/robolectric",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/android/support/functional/ComponentStructureFollowsControllerStructureApplication.java b/javatests/dagger/android/support/functional/ComponentStructureFollowsControllerStructureApplication.java
deleted file mode 100644
index 48e9a59..0000000
--- a/javatests/dagger/android/support/functional/ComponentStructureFollowsControllerStructureApplication.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.support.DaggerApplication;
-import dagger.android.support.functional.ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.BroadcastReceiverSubcomponent.BroadcastReceiverModule;
-import dagger.android.support.functional.ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.ContentProviderSubcomponent.ContentProviderModule;
-import dagger.android.support.functional.ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.InnerActivitySubcomponent.InnerActivityModule;
-import dagger.android.support.functional.ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.IntentServiceSubcomponent.IntentServiceModule;
-import dagger.android.support.functional.ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.ServiceSubcomponent.ServiceModule;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-
-public final class ComponentStructureFollowsControllerStructureApplication
-    extends DaggerApplication {
-
-  @Override
-  protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
-    return DaggerComponentStructureFollowsControllerStructureApplication_ApplicationComponent
-        .create();
-  }
-
-  @Component(modules = {ApplicationComponent.ApplicationModule.class, AndroidInjectionModule.class})
-  interface ApplicationComponent
-      extends AndroidInjector<ComponentStructureFollowsControllerStructureApplication> {
-    @Module(
-      subcomponents = {
-        ActivitySubcomponent.class,
-        InnerActivitySubcomponent.class,
-        ServiceSubcomponent.class,
-        IntentServiceSubcomponent.class,
-        BroadcastReceiverSubcomponent.class,
-        ContentProviderSubcomponent.class,
-      }
-    )
-    abstract class ApplicationModule {
-      @Provides
-      @IntoSet
-      static Class<?> addToComponentHierarchy() {
-        return ApplicationComponent.class;
-      }
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestActivity.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForTestActivity(
-          ActivitySubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(OuterClass.TestInnerClassActivity.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForInnerActivity(
-          InnerActivitySubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestService.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForService(
-          ServiceSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestIntentService.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForIntentService(
-          IntentServiceSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestBroadcastReceiver.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForBroadcastReceiver(
-          BroadcastReceiverSubcomponent.Builder builder);
-
-      @Binds
-      @IntoMap
-      @ClassKey(TestContentProvider.class)
-      abstract AndroidInjector.Factory<?> bindFactoryForContentProvider(
-          ContentProviderSubcomponent.Builder builder);
-    }
-
-    @Subcomponent(modules = ActivitySubcomponent.ActivityModule.class)
-    interface ActivitySubcomponent extends AndroidInjector<TestActivity> {
-      @Module(subcomponents = {ParentFragmentSubcomponent.class, DialogFragmentSubcomponent.class})
-      abstract class ActivityModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ActivitySubcomponent.class;
-        }
-
-        @Binds
-        @IntoMap
-        @ClassKey(TestParentFragment.class)
-        abstract AndroidInjector.Factory<?> bindFactoryForParentFragment(
-            ParentFragmentSubcomponent.Builder builder);
-
-        @Binds
-        @IntoMap
-        @ClassKey(TestDialogFragment.class)
-        abstract AndroidInjector.Factory<?> bindFactoryForDialogFragment(
-            DialogFragmentSubcomponent.Builder builder);
-      }
-
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestActivity> {}
-
-      @Subcomponent(modules = ParentFragmentSubcomponent.ParentFragmentModule.class)
-      interface ParentFragmentSubcomponent extends AndroidInjector<TestParentFragment> {
-        @Module(subcomponents = ChildFragmentSubcomponent.class)
-        abstract class ParentFragmentModule {
-          @Provides
-          @IntoSet
-          static Class<?> addToComponentHierarchy() {
-            return ParentFragmentSubcomponent.class;
-          }
-
-          @Binds
-          @IntoMap
-          @ClassKey(TestChildFragment.class)
-          abstract AndroidInjector.Factory<?> bindFactoryForChildFragment(
-              ChildFragmentSubcomponent.Builder builder);
-        }
-
-        @Subcomponent.Builder
-        abstract class Builder extends AndroidInjector.Builder<TestParentFragment> {}
-
-        @Subcomponent(modules = ChildFragmentSubcomponent.ChildFragmentModule.class)
-        interface ChildFragmentSubcomponent extends AndroidInjector<TestChildFragment> {
-          @Module
-          abstract class ChildFragmentModule {
-            @Provides
-            @IntoSet
-            static Class<?> addToComponentHierarchy() {
-              return ChildFragmentSubcomponent.class;
-            }
-          }
-
-          @Subcomponent.Builder
-          abstract class Builder extends AndroidInjector.Builder<TestChildFragment> {}
-        }
-      }
-
-      @Subcomponent(modules = DialogFragmentSubcomponent.DialogFragmentModule.class)
-      interface DialogFragmentSubcomponent extends AndroidInjector<TestDialogFragment> {
-        @Module
-        abstract class DialogFragmentModule {
-          @Provides
-          @IntoSet
-          static Class<?> addToComponentHierarchy() {
-            return DialogFragmentSubcomponent.class;
-          }
-        }
-
-        @Subcomponent.Builder
-        abstract class Builder extends AndroidInjector.Builder<TestDialogFragment> {}
-      }
-    }
-
-    @Subcomponent(modules = InnerActivityModule.class)
-    interface InnerActivitySubcomponent extends AndroidInjector<OuterClass.TestInnerClassActivity> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<OuterClass.TestInnerClassActivity> {}
-
-      @Module
-      abstract class InnerActivityModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return InnerActivitySubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = ServiceModule.class)
-    interface ServiceSubcomponent extends AndroidInjector<TestService> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestService> {}
-
-      @Module
-      abstract class ServiceModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ServiceSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = IntentServiceModule.class)
-    interface IntentServiceSubcomponent extends AndroidInjector<TestIntentService> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestIntentService> {}
-
-      @Module
-      abstract class IntentServiceModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return IntentServiceSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = BroadcastReceiverModule.class)
-    interface BroadcastReceiverSubcomponent extends AndroidInjector<TestBroadcastReceiver> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestBroadcastReceiver> {}
-
-      @Module
-      abstract class BroadcastReceiverModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return BroadcastReceiverSubcomponent.class;
-        }
-      }
-    }
-
-    @Subcomponent(modules = ContentProviderModule.class)
-    interface ContentProviderSubcomponent extends AndroidInjector<TestContentProvider> {
-      @Subcomponent.Builder
-      abstract class Builder extends AndroidInjector.Builder<TestContentProvider> {}
-
-      @Module
-      abstract class ContentProviderModule {
-        @Provides
-        @IntoSet
-        static Class<?> addToComponentHierarchy() {
-          return ContentProviderSubcomponent.class;
-        }
-      }
-    }
-  }
-}
diff --git a/javatests/dagger/android/support/functional/InjectorsTest.java b/javatests/dagger/android/support/functional/InjectorsTest.java
deleted file mode 100644
index c5cb150..0000000
--- a/javatests/dagger/android/support/functional/InjectorsTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Intent;
-import android.content.res.Configuration;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-public class InjectorsTest {
-  private ActivityController<TestActivity> activityController;
-  private TestActivity activity;
-  private TestParentFragment parentFragment;
-  private TestChildFragment childFragment;
-  private TestDialogFragment dialogFragment;
-  private TestService service;
-  private TestIntentService intentService;
-  private TestBroadcastReceiver broadcastReceiver;
-  private TestContentProvider contentProvider;
-
-  @Before
-  public void setUp() {
-    activityController = Robolectric.buildActivity(TestActivity.class);
-    activity = activityController.setup().get();
-    parentFragment =
-        (TestParentFragment)
-            activity.getSupportFragmentManager().findFragmentByTag("parent-fragment");
-    childFragment =
-        (TestChildFragment)
-            parentFragment.getChildFragmentManager().findFragmentByTag("child-fragment");
-    dialogFragment =
-        (TestDialogFragment)
-            activity.getSupportFragmentManager().findFragmentByTag("dialog-fragment");
-
-    service = Robolectric.buildService(TestService.class).create().get();
-    intentService = Robolectric.buildIntentService(TestIntentService.class).create().get();
-
-    broadcastReceiver = new TestBroadcastReceiver();
-    broadcastReceiver.onReceive(RuntimeEnvironment.application, new Intent());
-
-    contentProvider = Robolectric.setupContentProvider(TestContentProvider.class);
-  }
-
-  @Test
-  @Config(application = ComponentStructureFollowsControllerStructureApplication.class)
-  public void componentStructureFollowsControllerStructure() {
-    assertThat(activity.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.class);
-    assertThat(parentFragment.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.ParentFragmentSubcomponent.class);
-    assertThat(childFragment.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.ParentFragmentSubcomponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.ParentFragmentSubcomponent.ChildFragmentSubcomponent.class);
-    assertThat(dialogFragment.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ActivitySubcomponent.DialogFragmentSubcomponent.class);
-
-    assertThat(service.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ServiceSubcomponent.class);
-    assertThat(intentService.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .IntentServiceSubcomponent.class);
-
-    assertThat(broadcastReceiver.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .BroadcastReceiverSubcomponent.class);
-
-    assertThat(contentProvider.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .ContentProviderSubcomponent.class);
-
-    changeConfiguration();
-
-    OuterClass.TestInnerClassActivity innerClassActivity =
-        Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class);
-    assertThat(innerClassActivity.componentHierarchy)
-        .containsExactly(
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class,
-            ComponentStructureFollowsControllerStructureApplication.ApplicationComponent
-                .InnerActivitySubcomponent.class);
-  }
-
-  @Test
-  @Config(application = AllControllersAreDirectChildrenOfApplication.class)
-  public void allControllersAreDirectChildrenOfApplication() {
-    assertThat(activity.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ActivitySubcomponent
-                .class);
-    assertThat(parentFragment.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .ParentFragmentSubcomponent.class);
-    assertThat(childFragment.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .ChildFragmentSubcomponent.class);
-    assertThat(dialogFragment.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .DialogFragmentSubcomponent.class);
-
-    assertThat(service.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ServiceSubcomponent
-                .class);
-    assertThat(intentService.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .IntentServiceSubcomponent.class);
-
-    assertThat(broadcastReceiver.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .BroadcastReceiverSubcomponent.class);
-
-    assertThat(contentProvider.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .ContentProviderSubcomponent.class);
-
-    changeConfiguration();
-
-    OuterClass.TestInnerClassActivity innerClassActivity =
-        Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class);
-    assertThat(innerClassActivity.componentHierarchy)
-        .containsExactly(
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class,
-            AllControllersAreDirectChildrenOfApplication.ApplicationComponent
-                .InnerActivitySubcomponent.class);
-  }
-
-  @Test
-  @Config(application = UsesGeneratedModulesApplication.class)
-  public void usesGeneratedModules() {
-    assertThat(activity.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyActivitySubcomponent.class);
-    assertThat(parentFragment.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyParentFragmentSubcomponent.class);
-    assertThat(childFragment.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyChildFragmentSubcomponent.class);
-    assertThat(dialogFragment.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyDialogFragmentSubcomponent.class);
-
-    assertThat(service.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyServiceSubcomponent.class);
-    assertThat(intentService.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyIntentServiceSubcomponent.class);
-
-    assertThat(broadcastReceiver.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyBroadcastReceiverSubcomponent.class);
-
-    assertThat(contentProvider.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyContentProviderSubcomponent.class);
-
-    changeConfiguration();
-
-    TestActivityWithScope activityWithScope =
-        Robolectric.setupActivity(TestActivityWithScope.class);
-    assertThat(activityWithScope.scopedStringProvider.get())
-        .isSameInstanceAs(activityWithScope.scopedStringProvider.get());
-
-    OuterClass.TestInnerClassActivity innerClassActivity =
-        Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class);
-    assertThat(innerClassActivity.componentHierarchy)
-        .containsExactly(
-            UsesGeneratedModulesApplication.ApplicationComponent.class,
-            UsesGeneratedModulesApplication.DummyInnerActivitySubcomponent.class);
-  }
-
-  // https://github.com/google/dagger/issues/598
-  private void changeConfiguration() {
-    Configuration oldConfiguration = activity.getResources().getConfiguration();
-    Configuration newConfiguration = new Configuration(oldConfiguration);
-    newConfiguration.orientation =
-        oldConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE
-            ? Configuration.ORIENTATION_PORTRAIT
-            : Configuration.ORIENTATION_LANDSCAPE;
-    activityController.configurationChange(newConfiguration);
-  }
-}
diff --git a/javatests/dagger/android/support/functional/OuterClass.java b/javatests/dagger/android/support/functional/OuterClass.java
deleted file mode 100644
index e5d6ed5..0000000
--- a/javatests/dagger/android/support/functional/OuterClass.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.support.functional;
-
-import dagger.android.support.DaggerAppCompatActivity;
-import java.util.Set;
-import javax.inject.Inject;
-
-final class OuterClass {
-  public static class TestInnerClassActivity extends DaggerAppCompatActivity {
-    @Inject
-    Set<Class<?>> componentHierarchy;
-  }
-}
diff --git a/javatests/dagger/android/support/functional/TestActivity.java b/javatests/dagger/android/support/functional/TestActivity.java
deleted file mode 100644
index 84c44fd..0000000
--- a/javatests/dagger/android/support/functional/TestActivity.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import android.os.Bundle;
-import dagger.android.support.DaggerAppCompatActivity;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestActivity extends DaggerAppCompatActivity {
-  @Inject Set<Class<?>> componentHierarchy;
-
-  @Override
-  protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-
-    setContentView(R.layout.activity_layout);
-
-    getSupportFragmentManager()
-        .beginTransaction()
-        .add(new TestParentFragment(), "parent-fragment")
-        .add(new TestDialogFragment(), "dialog-fragment")
-        .commit();
-  }
-}
diff --git a/javatests/dagger/android/support/functional/TestActivityWithScope.java b/javatests/dagger/android/support/functional/TestActivityWithScope.java
deleted file mode 100644
index d7cb891..0000000
--- a/javatests/dagger/android/support/functional/TestActivityWithScope.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.android.support.DaggerAppCompatActivity;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-public final class TestActivityWithScope extends DaggerAppCompatActivity {
-  @Inject Provider<String> scopedStringProvider;
-}
diff --git a/javatests/dagger/android/support/functional/TestBroadcastReceiver.java b/javatests/dagger/android/support/functional/TestBroadcastReceiver.java
deleted file mode 100644
index edf93fe..0000000
--- a/javatests/dagger/android/support/functional/TestBroadcastReceiver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.android.DaggerBroadcastReceiver;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestBroadcastReceiver extends DaggerBroadcastReceiver {
-  @Inject Set<Class<?>> componentHierarchy;
-}
diff --git a/javatests/dagger/android/support/functional/TestChildFragment.java b/javatests/dagger/android/support/functional/TestChildFragment.java
deleted file mode 100644
index 781c578..0000000
--- a/javatests/dagger/android/support/functional/TestChildFragment.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.android.support.DaggerFragment;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestChildFragment extends DaggerFragment {
-  @Inject Set<Class<?>> componentHierarchy;
-}
diff --git a/javatests/dagger/android/support/functional/TestContentProvider.java b/javatests/dagger/android/support/functional/TestContentProvider.java
deleted file mode 100644
index 1668ce6..0000000
--- a/javatests/dagger/android/support/functional/TestContentProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.support.annotation.Nullable;
-import dagger.android.DaggerContentProvider;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestContentProvider extends DaggerContentProvider {
-  @Inject
-  Set<Class<?>> componentHierarchy;
-
-  @Nullable
-  @Override
-  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-      String sortOrder) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Nullable
-  @Override
-  public String getType(Uri uri) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Nullable
-  @Override
-  public Uri insert(Uri uri, ContentValues values) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public int delete(Uri uri, String selection, String[] selectionArgs) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/javatests/dagger/android/support/functional/TestDialogFragment.java b/javatests/dagger/android/support/functional/TestDialogFragment.java
deleted file mode 100644
index d499ee5..0000000
--- a/javatests/dagger/android/support/functional/TestDialogFragment.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import dagger.android.support.DaggerAppCompatDialogFragment;
-import java.util.Set;
-import javax.inject.Inject;
-
-public class TestDialogFragment extends DaggerAppCompatDialogFragment {
-  @Inject Set<Class<?>> componentHierarchy;
-}
diff --git a/javatests/dagger/android/support/functional/TestIntentService.java b/javatests/dagger/android/support/functional/TestIntentService.java
deleted file mode 100644
index 7f36e93..0000000
--- a/javatests/dagger/android/support/functional/TestIntentService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import android.content.Intent;
-import dagger.android.DaggerIntentService;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestIntentService extends DaggerIntentService {
-  @Inject Set<Class<?>> componentHierarchy;
-
-  public TestIntentService() {
-    super("TestIntentService");
-  }
-
-  @Override
-  protected void onHandleIntent(Intent intent) {}
-}
diff --git a/javatests/dagger/android/support/functional/TestParentFragment.java b/javatests/dagger/android/support/functional/TestParentFragment.java
deleted file mode 100644
index 6d2d6f4..0000000
--- a/javatests/dagger/android/support/functional/TestParentFragment.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import android.content.Context;
-import dagger.android.support.DaggerFragment;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestParentFragment extends DaggerFragment {
-  @Inject Set<Class<?>> componentHierarchy;
-
-  @Override
-  public void onAttach(Context context) {
-    super.onAttach(context);
-    getChildFragmentManager()
-        .beginTransaction()
-        .add(new TestChildFragment(), "child-fragment")
-        .commit();
-  }
-}
diff --git a/javatests/dagger/android/support/functional/TestService.java b/javatests/dagger/android/support/functional/TestService.java
deleted file mode 100644
index d3c6dc1..0000000
--- a/javatests/dagger/android/support/functional/TestService.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-import dagger.android.DaggerService;
-import java.io.FileDescriptor;
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class TestService extends DaggerService {
-  @Inject Set<Class<?>> componentHierarchy;
-
-  @Override
-  public IBinder onBind(Intent intent) {
-    return new MockBinder();
-  }
-
-  private static class MockBinder implements IBinder {
-    @Override
-    public String getInterfaceDescriptor() throws RemoteException {
-      return null;
-    }
-
-    @Override
-    public boolean pingBinder() {
-      return false;
-    }
-
-    @Override
-    public boolean isBinderAlive() {
-      return false;
-    }
-
-    @Override
-    public IInterface queryLocalInterface(String descriptor) {
-      return null;
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, String[] args) throws RemoteException {}
-
-    @Override
-    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {}
-
-    @Override
-    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
-      return false;
-    }
-
-    @Override
-    public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {}
-
-    @Override
-    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
-      return false;
-    }
-  }
-}
diff --git a/javatests/dagger/android/support/functional/UsesGeneratedModulesApplication.java b/javatests/dagger/android/support/functional/UsesGeneratedModulesApplication.java
deleted file mode 100644
index 002da89..0000000
--- a/javatests/dagger/android/support/functional/UsesGeneratedModulesApplication.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2017 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.android.support.functional;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.android.AndroidInjectionModule;
-import dagger.android.AndroidInjector;
-import dagger.android.ContributesAndroidInjector;
-import dagger.android.support.DaggerApplication;
-import dagger.multibindings.IntoSet;
-import java.lang.annotation.Retention;
-import java.util.UUID;
-import javax.inject.Scope;
-
-public final class UsesGeneratedModulesApplication extends DaggerApplication {
-
-  @Override
-  protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
-    return DaggerUsesGeneratedModulesApplication_ApplicationComponent.create();
-  }
-
-  @Component(modules = {ApplicationModule.class, AndroidInjectionModule.class})
-  interface ApplicationComponent extends AndroidInjector<UsesGeneratedModulesApplication> {}
-
-  @Module
-  abstract static class ApplicationModule {
-    @Provides
-    @IntoSet
-    static Class<?> addToComponentHierarchy() {
-      return ApplicationComponent.class;
-    }
-
-    @ActivityScope
-    @ContributesAndroidInjector(modules = ActivityScopedModule.class)
-    abstract TestActivityWithScope contributeTestActivityWithScopeInjector();
-
-    @ContributesAndroidInjector(modules = DummyActivitySubcomponent.AddToHierarchy.class)
-    abstract TestActivity contributeTestActivityInjector();
-
-    @ContributesAndroidInjector(modules = DummyInnerActivitySubcomponent.AddToHierarchy.class)
-    abstract OuterClass.TestInnerClassActivity contributeInnerActivityInjector();
-
-    @ContributesAndroidInjector(modules = DummyParentFragmentSubcomponent.AddToHierarchy.class)
-    abstract TestParentFragment contributeTestParentFragmentInjector();
-
-    @ContributesAndroidInjector(modules = DummyChildFragmentSubcomponent.AddToHierarchy.class)
-    abstract TestChildFragment contributeTestChildFragmentInjector();
-
-    @ContributesAndroidInjector(modules = DummyDialogFragmentSubcomponent.AddToHierarchy.class)
-    abstract TestDialogFragment contributeTestDialogFragmentInjector();
-
-    @ContributesAndroidInjector(modules = DummyServiceSubcomponent.AddToHierarchy.class)
-    abstract TestService contributeTestServiceInjector();
-
-    @ContributesAndroidInjector(modules = DummyIntentServiceSubcomponent.AddToHierarchy.class)
-    abstract TestIntentService contributeTestIntentServiceInjector();
-
-    @ContributesAndroidInjector(modules = DummyBroadcastReceiverSubcomponent.AddToHierarchy.class)
-    abstract TestBroadcastReceiver contributeTestBroadcastReceiverInjector();
-
-    @ContributesAndroidInjector(modules = DummyContentProviderSubcomponent.AddToHierarchy.class)
-    abstract TestContentProvider contributeTestContentProviderInjector();
-  }
-
-  @Retention(RUNTIME)
-  @Scope
-  @interface ActivityScope {}
-
-  @Module
-  static class ActivityScopedModule {
-    @Provides
-    @ActivityScope
-    static String provideScopedString() {
-      return UUID.randomUUID().toString();
-    }
-  }
-
-  interface DummyActivitySubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyActivitySubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyInnerActivitySubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyInnerActivitySubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyParentFragmentSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyParentFragmentSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyChildFragmentSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyChildFragmentSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyDialogFragmentSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyDialogFragmentSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyServiceSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyServiceSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyIntentServiceSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyIntentServiceSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyBroadcastReceiverSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyBroadcastReceiverSubcomponent.class;
-      }
-    }
-  }
-
-  interface DummyContentProviderSubcomponent {
-    @Module
-    abstract class AddToHierarchy {
-      @Provides
-      @IntoSet
-      static Class<?> addDummyValueToComponentHierarchy() {
-        return DummyContentProviderSubcomponent.class;
-      }
-    }
-  }
-}
diff --git a/javatests/dagger/android/support/functional/res/layout/activity_layout.xml b/javatests/dagger/android/support/functional/res/layout/activity_layout.xml
deleted file mode 100644
index d886d97..0000000
--- a/javatests/dagger/android/support/functional/res/layout/activity_layout.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  ~ Copyright (C) 2016 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.
-  -->
-
-<FrameLayout
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:id="@+id/fragment_container"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent" />
diff --git a/javatests/dagger/functional/A.java b/javatests/dagger/functional/A.java
deleted file mode 100644
index c295dc1..0000000
--- a/javatests/dagger/functional/A.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class A {
-  @Inject A() {}
-}
diff --git a/javatests/dagger/functional/AbstractMembersInjectingBaseClass.java b/javatests/dagger/functional/AbstractMembersInjectingBaseClass.java
deleted file mode 100644
index fcab318..0000000
--- a/javatests/dagger/functional/AbstractMembersInjectingBaseClass.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-abstract class AbstractMembersInjectingBaseClass {
-  @Inject Thing thing;
-}
-
diff --git a/javatests/dagger/functional/AbstractMiddleClassWithoutMembers.java b/javatests/dagger/functional/AbstractMiddleClassWithoutMembers.java
deleted file mode 100644
index 4ff55eb..0000000
--- a/javatests/dagger/functional/AbstractMiddleClassWithoutMembers.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-abstract class AbstractMiddleClassWithoutMembers extends AbstractMembersInjectingBaseClass {
-}
-
diff --git a/javatests/dagger/functional/B.java b/javatests/dagger/functional/B.java
deleted file mode 100644
index 55d05af..0000000
--- a/javatests/dagger/functional/B.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class B {
-  @Inject B() {}
-}
diff --git a/javatests/dagger/functional/BUILD b/javatests/dagger/functional/BUILD
deleted file mode 100644
index f417bec..0000000
--- a/javatests/dagger/functional/BUILD
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Functional tests for Dagger
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "SOURCE_7_TARGET_7",
-)
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "functional_tests",
-    srcs = glob(
-        ["**/*.java"],
-    ),
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    lib_javacopts = SOURCE_7_TARGET_7,
-    # NOTE: This should not depend on Guava or jsr305 to ensure that Dagger can be
-    # used without Guava and jsr305 deps.
-    test_only_deps = [
-        "@google_bazel_common//third_party/java/guava:testlib",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/truth",
-        "@google_bazel_common//third_party/java/junit",
-    ],
-    deps = [
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/auto:factory",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-    ],
-)
diff --git a/javatests/dagger/functional/BasicAbstractClassComponent.java b/javatests/dagger/functional/BasicAbstractClassComponent.java
deleted file mode 100644
index 2bd849d..0000000
--- a/javatests/dagger/functional/BasicAbstractClassComponent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-
-/**
- * This component tests behavior equivalent to {@link BasicComponent}, but as an abstract class
- * rather than an interface.
- */
-@Component(modules = {PrimitivesModule.class, NullableModule.class})
-abstract class BasicAbstractClassComponent implements BasicComponent {
-  void throwAParty() {
-    throw new RuntimeException("Paaarrrrrtaaaaaaaay!");
-  }
-}
diff --git a/javatests/dagger/functional/BasicComponent.java b/javatests/dagger/functional/BasicComponent.java
deleted file mode 100644
index 295c1e1..0000000
--- a/javatests/dagger/functional/BasicComponent.java
+++ /dev/null
@@ -1,93 +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.functional;
-
-import dagger.Component;
-import dagger.Lazy;
-import dagger.MembersInjector;
-import dagger.functional.NullableModule.Nullable;
-import javax.inject.Provider;
-
-@Component(modules = {PrimitivesModule.class, NullableModule.class})
-interface BasicComponent
-    extends Injector<Thing>,
-        // Implements two types that define the same method, not overridden here, to test that the
-        // method is implemented only once.
-        ComponentSupertypeOne,
-        ComponentSupertypeTwo {
-  byte getByte();
-  char getChar();
-  short getShort();
-  int getInt();
-  long getLong();
-  boolean getBoolean();
-  float getFloat();
-  double getDouble();
-
-  Byte getBoxedByte();
-  Character getBoxedChar();
-  Short getBoxedShort();
-  Integer getBoxedInt();
-  Long getBoxedLong();
-  Boolean getBoxedBoolean();
-  Float getBoxedFloat();
-  Double getBoxedDouble();
-
-  Provider<Byte> getByteProvider();
-  Provider<Character> getCharProvider();
-  Provider<Short> getShortProvider();
-  Provider<Integer> getIntProvider();
-  Provider<Long> getLongProvider();
-  Provider<Boolean> getBooleanProvider();
-  Provider<Float> getFloatProvider();
-  Provider<Double> getDoubleProvider();
-
-  byte[] getByteArray();
-  char[] getCharArray();
-  short[] getShortArray();
-  int[] getIntArray();
-  long[] getLongArray();
-  boolean[] getBooleanArray();
-  float[] getFloatArray();
-  double[] getDoubleArray();
-
-  Provider<byte[]> getByteArrayProvider();
-  Provider<char[]> getCharArrayProvider();
-  Provider<short[]> getShortArrayProvider();
-  Provider<int[]> getIntArrayProvider();
-  Provider<long[]> getLongArrayProvider();
-  Provider<boolean[]> getBooleanArrayProvider();
-  Provider<float[]> getFloatArrayProvider();
-  Provider<double[]> getDoubleArrayProvider();
-
-  Object noOpMembersInjection(Object obviouslyDoesNotHaveMembersToInject);
-
-  Thing thing();
-  InjectedThing injectedThing();
-  Provider<InjectedThing> injectedThingProvider();
-  Lazy<InjectedThing> lazyInjectedThing();
-  Provider<Lazy<InjectedThing>> lazyInjectedThingProvider();
-  MembersInjector<InjectedThing> injectedThingMembersInjector();
-  
-  @Nullable Object nullObject();
-  Provider<Object> nullObjectProvider();
-  Lazy<Object> lazyNullObject();
-
-  TypeWithInheritedMembersInjection typeWithInheritedMembersInjection();
-  MembersInjector<TypeWithInheritedMembersInjection>
-      typeWithInheritedMembersInjectionMembersInjector();
-}
diff --git a/javatests/dagger/functional/BasicTest.java b/javatests/dagger/functional/BasicTest.java
deleted file mode 100644
index 80fc5e6..0000000
--- a/javatests/dagger/functional/BasicTest.java
+++ /dev/null
@@ -1,139 +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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-import static dagger.functional.PrimitivesModule.BOUND_BOOLEAN;
-import static dagger.functional.PrimitivesModule.BOUND_BOOLEAN_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_BYTE;
-import static dagger.functional.PrimitivesModule.BOUND_BYTE_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_CHAR;
-import static dagger.functional.PrimitivesModule.BOUND_CHAR_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_DOUBLE;
-import static dagger.functional.PrimitivesModule.BOUND_DOUBLE_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_FLOAT;
-import static dagger.functional.PrimitivesModule.BOUND_FLOAT_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_INT;
-import static dagger.functional.PrimitivesModule.BOUND_INT_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_LONG;
-import static dagger.functional.PrimitivesModule.BOUND_LONG_ARRAY;
-import static dagger.functional.PrimitivesModule.BOUND_SHORT;
-import static dagger.functional.PrimitivesModule.BOUND_SHORT_ARRAY;
-
-import dagger.Lazy;
-import javax.inject.Provider;
-import org.junit.experimental.theories.DataPoint;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.runner.RunWith;
-
-@RunWith(Theories.class)
-public class BasicTest {
-  @DataPoint
-  public static final BasicComponent basicComponent = DaggerBasicComponent.create();
-  @DataPoint
-  public static final BasicComponent abstractClassBasicComponent =
-      DaggerBasicAbstractClassComponent.create();
-
-  @Theory public void primitives(BasicComponent basicComponent) {
-    assertThat(basicComponent.getByte()).isEqualTo(BOUND_BYTE);
-    assertThat(basicComponent.getChar()).isEqualTo(BOUND_CHAR);
-    assertThat(basicComponent.getShort()).isEqualTo(BOUND_SHORT);
-    assertThat(basicComponent.getInt()).isEqualTo(BOUND_INT);
-    assertThat(basicComponent.getLong()).isEqualTo(BOUND_LONG);
-    assertThat(basicComponent.getBoolean()).isEqualTo(BOUND_BOOLEAN);
-    assertThat(basicComponent.getFloat()).isEqualTo(BOUND_FLOAT);
-    assertThat(basicComponent.getDouble()).isEqualTo(BOUND_DOUBLE);
-  }
-
-  @Theory public void boxedPrimitives(BasicComponent basicComponent) {
-    assertThat(basicComponent.getBoxedByte()).isEqualTo(new Byte(BOUND_BYTE));
-    assertThat(basicComponent.getBoxedChar()).isEqualTo(new Character(BOUND_CHAR));
-    assertThat(basicComponent.getBoxedShort()).isEqualTo(new Short(BOUND_SHORT));
-    assertThat(basicComponent.getBoxedInt()).isEqualTo(new Integer(BOUND_INT));
-    assertThat(basicComponent.getBoxedLong()).isEqualTo(new Long(BOUND_LONG));
-    assertThat(basicComponent.getBoxedBoolean()).isEqualTo(new Boolean(BOUND_BOOLEAN));
-    assertThat(basicComponent.getBoxedFloat()).isEqualTo(BOUND_FLOAT);
-    assertThat(basicComponent.getBoxedDouble()).isEqualTo(BOUND_DOUBLE);
-  }
-
-  @Theory public void boxedPrimitiveProviders(BasicComponent basicComponent) {
-    assertThat(basicComponent.getByteProvider().get()).isEqualTo(new Byte(BOUND_BYTE));
-    assertThat(basicComponent.getCharProvider().get()).isEqualTo(new Character(BOUND_CHAR));
-    assertThat(basicComponent.getShortProvider().get()).isEqualTo(new Short(BOUND_SHORT));
-    assertThat(basicComponent.getIntProvider().get()).isEqualTo(new Integer(BOUND_INT));
-    assertThat(basicComponent.getLongProvider().get()).isEqualTo(new Long(BOUND_LONG));
-    assertThat(basicComponent.getBooleanProvider().get()).isEqualTo(new Boolean(BOUND_BOOLEAN));
-    assertThat(basicComponent.getFloatProvider().get()).isEqualTo(BOUND_FLOAT);
-    assertThat(basicComponent.getDoubleProvider().get()).isEqualTo(BOUND_DOUBLE);
-  }
-
-  @Theory public void primitiveArrays(BasicComponent basicComponent) {
-    assertThat(basicComponent.getByteArray()).isSameInstanceAs(BOUND_BYTE_ARRAY);
-    assertThat(basicComponent.getCharArray()).isSameInstanceAs(BOUND_CHAR_ARRAY);
-    assertThat(basicComponent.getShortArray()).isSameInstanceAs(BOUND_SHORT_ARRAY);
-    assertThat(basicComponent.getIntArray()).isSameInstanceAs(BOUND_INT_ARRAY);
-    assertThat(basicComponent.getLongArray()).isSameInstanceAs(BOUND_LONG_ARRAY);
-    assertThat(basicComponent.getBooleanArray()).isSameInstanceAs(BOUND_BOOLEAN_ARRAY);
-    assertThat(basicComponent.getFloatArray()).isSameInstanceAs(BOUND_FLOAT_ARRAY);
-    assertThat(basicComponent.getDoubleArray()).isSameInstanceAs(BOUND_DOUBLE_ARRAY);
-  }
-
-  @Theory public void primitiveArrayProviders(BasicComponent basicComponent) {
-    assertThat(basicComponent.getByteArrayProvider().get()).isSameInstanceAs(BOUND_BYTE_ARRAY);
-    assertThat(basicComponent.getCharArrayProvider().get()).isSameInstanceAs(BOUND_CHAR_ARRAY);
-    assertThat(basicComponent.getShortArrayProvider().get()).isSameInstanceAs(BOUND_SHORT_ARRAY);
-    assertThat(basicComponent.getIntArrayProvider().get()).isSameInstanceAs(BOUND_INT_ARRAY);
-    assertThat(basicComponent.getLongArrayProvider().get()).isSameInstanceAs(BOUND_LONG_ARRAY);
-    assertThat(basicComponent.getBooleanArrayProvider().get())
-        .isSameInstanceAs(BOUND_BOOLEAN_ARRAY);
-    assertThat(basicComponent.getFloatArrayProvider().get()).isSameInstanceAs(BOUND_FLOAT_ARRAY);
-    assertThat(basicComponent.getDoubleArrayProvider().get()).isSameInstanceAs(BOUND_DOUBLE_ARRAY);
-  }
-
-  @Theory public void noOpMembersInjection(BasicComponent basicComponent) {
-    Object object = new Object();
-    assertThat(basicComponent.noOpMembersInjection(object)).isSameInstanceAs(object);
-  }
-
-  @Theory public void basicObject_noDeps(BasicComponent basicComponent) {
-    assertThat(basicComponent.thing()).isNotNull();
-  }
-
-  @Theory public void inheritedMembersInjection(BasicComponent basicComponent) {
-    assertThat(basicComponent.typeWithInheritedMembersInjection().thing).isNotNull();
-  }
-  
-  @Theory
-  public void nullableInjection(BasicComponent basicComponent) {
-    assertThat(basicComponent.nullObject()).isNull();
-    assertThat(basicComponent.nullObjectProvider().get()).isNull();
-    assertThat(basicComponent.lazyNullObject().get()).isNull();
-  }
-  
-  @Theory
-  public void providerOfLazy(BasicComponent basicComponent) {
-    Provider<Lazy<InjectedThing>> lazyInjectedThingProvider =
-        basicComponent.lazyInjectedThingProvider();
-    Lazy<InjectedThing> lazyInjectedThing1 = lazyInjectedThingProvider.get();
-    Lazy<InjectedThing> lazyInjectedThing2 = lazyInjectedThingProvider.get();
-    assertThat(lazyInjectedThing2).isNotSameInstanceAs(lazyInjectedThing1);
-    assertThat(lazyInjectedThing1.get()).isSameInstanceAs(lazyInjectedThing1.get());
-    assertThat(lazyInjectedThing2.get()).isSameInstanceAs(lazyInjectedThing2.get());
-    assertThat(lazyInjectedThing2.get()).isNotSameInstanceAs(lazyInjectedThing1.get());
-  }
-}
diff --git a/javatests/dagger/functional/BooleanKey.java b/javatests/dagger/functional/BooleanKey.java
deleted file mode 100644
index 28e1c08..0000000
--- a/javatests/dagger/functional/BooleanKey.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-@MapKey(unwrapValue = true)
-@interface BooleanKey {
-  boolean value();
-}
diff --git a/javatests/dagger/functional/BoundedGenericComponent.java b/javatests/dagger/functional/BoundedGenericComponent.java
deleted file mode 100644
index 270316e..0000000
--- a/javatests/dagger/functional/BoundedGenericComponent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-@Component(modules = BoundedGenericModule.class)
-interface BoundedGenericComponent {
-  BoundedGenerics<Integer, ArrayList<String>, LinkedList<CharSequence>, Integer, List<Integer>>
-      bounds1();
-  BoundedGenerics<Double, LinkedList<String>, LinkedList<Comparable<String>>, Double, Set<Double>>
-      bounds2();
-}
diff --git a/javatests/dagger/functional/BoundedGenericModule.java b/javatests/dagger/functional/BoundedGenericModule.java
deleted file mode 100644
index b630cd6..0000000
--- a/javatests/dagger/functional/BoundedGenericModule.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-@Module
-class BoundedGenericModule {
-
-  @Provides
-  Integer provideInteger() {
-    return 1;
-  }
-
-  @Provides
-  Double provideDouble() {
-    return 2d;
-  }
-
-  @Provides
-  ArrayList<String> provideArrayListString() {
-    ArrayList<String> list = new ArrayList<>();
-    list.add("arrayListOfString");
-    return list;
-  }
-
-  @Provides
-  LinkedList<String> provideLinkedListString() {
-    LinkedList<String> list = new LinkedList<>();
-    list.add("linkedListOfString");
-    return list;
-  }
-
-  @Provides
-  LinkedList<CharSequence> provideLinkedListCharSeq() {
-    LinkedList<CharSequence> list = new LinkedList<>();
-    list.add("linkedListOfCharSeq");
-    return list;
-  }
-
-  @Provides
-  @SuppressWarnings("unchecked")
-  LinkedList<Comparable<String>> provideArrayListOfComparableString() {
-    LinkedList<Comparable<String>> list = new LinkedList<>();
-    list.add("arrayListOfComparableOfString");
-    return list;
-  }
-
-  @Provides
-  List<Integer> provideListOfInteger() {
-    LinkedList<Integer> list = new LinkedList<>();
-    list.add(3);
-    return list;
-  }
-
-  @Provides
-  Set<Double> provideSetOfDouble() {
-    Set<Double> set = new HashSet<>();
-    set.add(4d);
-    return set;
-  }
-}
diff --git a/javatests/dagger/functional/BoundedGenerics.java b/javatests/dagger/functional/BoundedGenerics.java
deleted file mode 100644
index 812cd04..0000000
--- a/javatests/dagger/functional/BoundedGenerics.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import java.util.List;
-import javax.inject.Inject;
-
-class BoundedGenerics<A extends Number & Comparable<? super A>, 
-      B extends List<? extends CharSequence>,
-      C extends List<? super String>,
-      D extends A,
-      E extends Iterable<D>> {
-  
-  final A a;
-  final B b;
-  final C c;
-  final D d;
-  final E e;
-  
-  @Inject BoundedGenerics(A a, B b, C c, D d, E e) {
-    this.a = a;
-    this.b = b;
-    this.c = c;
-    this.d = d;
-    this.e = e;
-  }
-
-}
diff --git a/javatests/dagger/functional/BoxedPrimitives.java b/javatests/dagger/functional/BoxedPrimitives.java
deleted file mode 100644
index adb61f2..0000000
--- a/javatests/dagger/functional/BoxedPrimitives.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import javax.inject.Provider;
-
-interface BoxedPrimitives {
-  interface Dependency {
-    int primitive();
-  }
-
-  @Component(dependencies = Dependency.class)
-  interface ConsumesPrimitiveThroughDependency {
-    Provider<Integer> providerOfBoxedPrimitive();
-  }
-
-  @Module
-  class PrimitiveModule {
-    @Provides
-    static int providePrimitive() {
-      return 1;
-    }
-  }
-
-  @Component(modules = PrimitiveModule.class)
-  interface ConsumesPrimitiveFromProvidesMethod {
-    Provider<Integer> providerOfBoxedPrimitive();
-  }
-
-}
diff --git a/javatests/dagger/functional/ByteKey.java b/javatests/dagger/functional/ByteKey.java
deleted file mode 100644
index f0ee7ec..0000000
--- a/javatests/dagger/functional/ByteKey.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-@MapKey(unwrapValue = true)
-@interface ByteKey {
-  byte value();
-}
diff --git a/javatests/dagger/functional/CharKey.java b/javatests/dagger/functional/CharKey.java
deleted file mode 100644
index 3e12785..0000000
--- a/javatests/dagger/functional/CharKey.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-@MapKey(unwrapValue = true)
-@interface CharKey {
-  char value();
-}
diff --git a/javatests/dagger/functional/ChildDoubleModule.java b/javatests/dagger/functional/ChildDoubleModule.java
deleted file mode 100644
index cff8f0b..0000000
--- a/javatests/dagger/functional/ChildDoubleModule.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.ArrayList;
-import java.util.List;
-
-@Module
-class ChildDoubleModule extends ParentModule<Double, String, List<Double>> {
-
-  @Provides Double provideDouble() {
-    return 3d;
-  }
-
-  @Provides List<Double> provideListOfDouble() {
-    List<Double> list = new ArrayList<>();
-    list.add(4d);
-    return list;
-  }
-
-}
diff --git a/javatests/dagger/functional/ChildIntegerModule.java b/javatests/dagger/functional/ChildIntegerModule.java
deleted file mode 100644
index 45c7c1a..0000000
--- a/javatests/dagger/functional/ChildIntegerModule.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.ArrayList;
-import java.util.List;
-
-@Module
-class ChildIntegerModule extends ParentModule<Integer, String, List<Integer>> {
-
-  @Provides Integer provideInteger() {
-    return 1;
-  }
-
-  @Provides List<Integer> provideListOfInteger() {
-    List<Integer> list = new ArrayList<>();
-    list.add(2);
-    return list;
-  }
-
-}
diff --git a/javatests/dagger/functional/ComplexGenerics.java b/javatests/dagger/functional/ComplexGenerics.java
deleted file mode 100644
index 9309583..0000000
--- a/javatests/dagger/functional/ComplexGenerics.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Lazy;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-class ComplexGenerics {
-  
-  final Generic2<Generic<A>> g2ga;
-  final Lazy<Generic2<Generic<A>>> g2gaLazy;
-  final Provider<Generic2<Generic<A>>> g2gaProvider;
-  final Generic2<Generic<B>> g2gb;
-  final Lazy<Generic2<Generic<B>>> g2gbLazy;
-  final Provider<Generic2<Generic<B>>> g2gbProvider;
-  final Generic2<A> g2a;
-  final Generic<Generic2<A>> gg2a;
-  final Generic<Generic2<B>> gg2b;
-  
-  @Inject ComplexGenerics(
-      Generic2<Generic<A>> g2ga,
-      Lazy<Generic2<Generic<A>>> g2gaLazy,
-      Provider<Generic2<Generic<A>>> g2gaProvider,
-      Generic2<Generic<B>> g2gb,
-      Lazy<Generic2<Generic<B>>> g2gbLazy,
-      Provider<Generic2<Generic<B>>> g2gbProvider,
-      Generic2<A> g2a,
-      Generic<Generic2<A>> gg2a,
-      Generic<Generic2<B>> gg2b) {
-    this.g2ga = g2ga;
-    this.g2gaLazy = g2gaLazy;
-    this.g2gaProvider = g2gaProvider;
-    this.g2gb = g2gb;
-    this.g2gbLazy = g2gbLazy;
-    this.g2gbProvider = g2gbProvider;
-    this.g2a = g2a;
-    this.gg2a = gg2a;
-    this.gg2b = gg2b;
-  }
-}
diff --git a/javatests/dagger/functional/ComponentDependsOnGeneratedCode.java b/javatests/dagger/functional/ComponentDependsOnGeneratedCode.java
deleted file mode 100644
index 9c44c5c..0000000
--- a/javatests/dagger/functional/ComponentDependsOnGeneratedCode.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-
-/**
- * A component that indirectly depends on code generated by another processor, in this case
- * {@link com.google.auto.factory.AutoFactory}. Neither this type nor its immediately referenced
- * types are generated, but {@link NeedsFactory} depends on the generated
- * {@link NeedsFactory_SomethingFactory}.
- *
- */
-@Component
-interface ComponentDependsOnGeneratedCode {
-  NeedsFactory needsFactory();
-}
diff --git a/javatests/dagger/functional/ComponentMethodTest.java b/javatests/dagger/functional/ComponentMethodTest.java
deleted file mode 100644
index 5e53ea4..0000000
--- a/javatests/dagger/functional/ComponentMethodTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional;
-
-import dagger.Component;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * This is a regression test that makes sure component method order does not affect initialization
- * order.
- */
-@RunWith(JUnit4.class)
-public final class ComponentMethodTest {
-
-  static final class Dep1 {
-
-    @Inject
-    Dep1(Dep2 dep2) {}
-  }
-
-  static final class Dep2 {
-
-    @Inject
-    Dep2(Dep3 dep3) {}
-  }
-
-  static final class Dep3 {
-
-    @Inject
-    Dep3() {}
-  }
-
-  @Component
-  interface NonTopologicalOrderComponent {
-
-    Provider<Dep1> dep1Provider();
-
-    Provider<Dep2> dep2Provider();
-  }
-
-  @Component
-  interface TopologicalOrderComponent {
-
-    Provider<Dep2> dep2Provider();
-
-    Provider<Dep1> dep1Provider();
-  }
-
-  @Test
-  public void testNonTopologicalOrderComponent() throws Exception {
-    NonTopologicalOrderComponent component =
-        DaggerComponentMethodTest_NonTopologicalOrderComponent.create();
-    component.dep1Provider().get();
-    component.dep2Provider().get();
-  }
-
-  @Test
-  public void testTopologicalOrderComponent() throws Exception {
-    TopologicalOrderComponent component =
-        DaggerComponentMethodTest_TopologicalOrderComponent.create();
-    component.dep1Provider().get();
-    component.dep2Provider().get();
-  }
-}
diff --git a/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCode.java b/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCode.java
deleted file mode 100644
index a26292a..0000000
--- a/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCode.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-
-/**
- * A component whose supertype depends on code generated by another processor, in this case
- * {@link com.google.auto.factory.AutoFactory}.
- *
- */
-@Component
-interface ComponentSupertypeDependsOnGeneratedCode
-    extends ComponentSupertypeDependsOnGeneratedCodeInterface {}
diff --git a/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCodeInterface.java b/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCodeInterface.java
deleted file mode 100644
index 7744d19..0000000
--- a/javatests/dagger/functional/ComponentSupertypeDependsOnGeneratedCodeInterface.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-interface ComponentSupertypeDependsOnGeneratedCodeInterface {
-  NeedsFactory_SomethingFactory somethingFactory();
-}
diff --git a/javatests/dagger/functional/ComponentSupertypeOne.java b/javatests/dagger/functional/ComponentSupertypeOne.java
deleted file mode 100644
index c63d1da..0000000
--- a/javatests/dagger/functional/ComponentSupertypeOne.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional;
-
-public interface ComponentSupertypeOne {
-  Thing inheritedThing();
-}
diff --git a/javatests/dagger/functional/ComponentSupertypeTwo.java b/javatests/dagger/functional/ComponentSupertypeTwo.java
deleted file mode 100644
index 3c8312b..0000000
--- a/javatests/dagger/functional/ComponentSupertypeTwo.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional;
-
-public interface ComponentSupertypeTwo {
-  Thing inheritedThing();
-}
diff --git a/javatests/dagger/functional/ComponentWithReusableBindings.java b/javatests/dagger/functional/ComponentWithReusableBindings.java
deleted file mode 100644
index afad0d7..0000000
--- a/javatests/dagger/functional/ComponentWithReusableBindings.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-import dagger.Subcomponent;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-@Component(modules = ComponentWithReusableBindings.ReusableBindingsModule.class)
-interface ComponentWithReusableBindings {
-
-  @Qualifier
-  @interface InParent {}
-
-  @Qualifier
-  @interface InChildren {}
-
-  @InParent
-  Object reusableInParent();
-
-  ChildOne childOne();
-
-  ChildTwo childTwo();
-
-  // b/77150738
-  int primitive();
-
-  // b/77150738: This is used as a regression test for fastInit mode's switching providers. In
-  // particular, it occurs when a @Provides method returns the boxed type but the component method
-  // returns the unboxed type, and the instance is requested from a SwitchingProvider.
-  boolean unboxedPrimitive();
-
-  // b/77150738
-  Provider<Boolean> booleanProvider();
-
-  @Subcomponent
-  interface ChildOne {
-    @InParent
-    Object reusableInParent();
-
-    @InChildren
-    Object reusableInChild();
-  }
-
-  @Subcomponent
-  interface ChildTwo {
-    @InParent
-    Object reusableInParent();
-
-    @InChildren
-    Object reusableInChild();
-  }
-
-  @Module
-  static class ReusableBindingsModule {
-    @Provides
-    @Reusable
-    @InParent
-    static Object inParent() {
-      return new Object();
-    }
-
-    @Provides
-    @Reusable
-    @InChildren
-    static Object inChildren() {
-      return new Object();
-    }
-
-    // b/77150738
-    @Provides
-    @Reusable
-    static int primitive() {
-      return 0;
-    }
-
-    // b/77150738
-    @Provides
-    @Reusable
-    static Boolean boxedPrimitive() {
-      return false;
-    }
-  }
-}
diff --git a/javatests/dagger/functional/ComponentsWithNestedModules.java b/javatests/dagger/functional/ComponentsWithNestedModules.java
deleted file mode 100644
index a42dd73..0000000
--- a/javatests/dagger/functional/ComponentsWithNestedModules.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-
-// https://github.com/google/dagger/issues/279
-public class ComponentsWithNestedModules {
-  @Component(modules = RegularComponent.SharedModule.class)
-  public interface RegularComponent {
-    @Module class SharedModule {}
-  }
-
-  @Component(modules = ExtendsRegularComponent.SharedModule.class)
-  public interface ExtendsRegularComponent extends RegularComponent {
-    @Module(includes = RegularComponent.SharedModule.class)
-    class SharedModule {}
-  }
-}
diff --git a/javatests/dagger/functional/DependsOnGeneratedCodeTest.java b/javatests/dagger/functional/DependsOnGeneratedCodeTest.java
deleted file mode 100644
index ca7631f..0000000
--- a/javatests/dagger/functional/DependsOnGeneratedCodeTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * @see <a href="http://b/19435358">Bug 19435358</a>
- */
-@RunWith(JUnit4.class)
-public class DependsOnGeneratedCodeTest {
-  @Test public void testComponentDependsOnGeneratedCode() {
-    assertThat(DaggerComponentDependsOnGeneratedCode.create().needsFactory()).isNotNull();
-  }
-}
diff --git a/javatests/dagger/functional/Generic.java b/javatests/dagger/functional/Generic.java
deleted file mode 100644
index 9e77efe..0000000
--- a/javatests/dagger/functional/Generic.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-public class Generic<T> {
-  final T t;
-
-  @Inject public Generic(T t) {
-    this.t = t;
-  }
-}
diff --git a/javatests/dagger/functional/Generic2.java b/javatests/dagger/functional/Generic2.java
deleted file mode 100644
index f53c0f8..0000000
--- a/javatests/dagger/functional/Generic2.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-public class Generic2<T> {
-  final T t;
-
-  @Inject Generic2(T t) {
-    this.t = t;
-  }
-}
diff --git a/javatests/dagger/functional/GenericChild.java b/javatests/dagger/functional/GenericChild.java
deleted file mode 100644
index bb7330e..0000000
--- a/javatests/dagger/functional/GenericChild.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class GenericChild<T> extends GenericParent<T, B> {
-  
-  A registeredA;
-  T registeredT;
-  
-  @Inject GenericChild() {}
-  
-  @Inject A a;
-  @Inject T t;
-  
-  @Inject void registerA(A a) { this.registeredA = a; }
-  @Inject void registerT(T t) { this.registeredT = t; }
-
-}
diff --git a/javatests/dagger/functional/GenericComponent.java b/javatests/dagger/functional/GenericComponent.java
deleted file mode 100644
index e27df3b..0000000
--- a/javatests/dagger/functional/GenericComponent.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.functional.GenericComponent.NongenericModule;
-import dagger.functional.sub.Exposed;
-import dagger.functional.sub.PublicSubclass;
-import java.util.Arrays;
-import java.util.List;
-import javax.inject.Provider;
-
-@Component(modules = {ChildDoubleModule.class, ChildIntegerModule.class, NongenericModule.class})
-interface GenericComponent {
-  ReferencesGeneric referencesGeneric();
-  GenericDoubleReferences<A> doubleGenericA();
-  GenericDoubleReferences<B> doubleGenericB();
-  ComplexGenerics complexGenerics();
-  GenericNoDeps<A> noDepsA();
-  GenericNoDeps<B> noDepsB();
-
-  void injectA(GenericChild<A> childA);
-  void injectB(GenericChild<B> childB);
-
-  Exposed exposed();
-  PublicSubclass publicSubclass();
-  
-  Iterable<Integer> iterableInt();
-  Iterable<Double> iterableDouble();
-
-  Provider<List<String>> stringsProvider(); // b/71595104
-
-  // b/71595104
-  @Module
-  abstract class GenericModule<T> {
-    // Note that for subclasses that use String for T, this factory will still need two
-    // Provider<String> framework dependencies.
-    @Provides
-    List<T> list(T t, String string) {
-      return Arrays.asList(t);
-    }
-  }
-
-  // b/71595104
-  @Module
-  class NongenericModule extends GenericModule<String> {
-    @Provides
-    static String string() {
-      return "string";
-    }
-  }
-}
diff --git a/javatests/dagger/functional/GenericDoubleReferences.java b/javatests/dagger/functional/GenericDoubleReferences.java
deleted file mode 100644
index ff79a98..0000000
--- a/javatests/dagger/functional/GenericDoubleReferences.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class GenericDoubleReferences<T> {
-  final T t;
-  final T t2;
-  final Thing a;
-  final Thing a2;
-
-  @Inject GenericDoubleReferences(T t, Thing a, T t2, Thing a2) {
-    this.t = t;
-    this.a = a;
-    this.t2 = t2;
-    this.a2 = a2;
-  }
-}
diff --git a/javatests/dagger/functional/GenericNoDeps.java b/javatests/dagger/functional/GenericNoDeps.java
deleted file mode 100644
index c3f38b4..0000000
--- a/javatests/dagger/functional/GenericNoDeps.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class GenericNoDeps<T> {
-  
-  @Inject GenericNoDeps() {}
-
-}
diff --git a/javatests/dagger/functional/GenericParent.java b/javatests/dagger/functional/GenericParent.java
deleted file mode 100644
index 13f9e2f..0000000
--- a/javatests/dagger/functional/GenericParent.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-class GenericParent<X, Y> {
-  
-  Provider<X> registeredX;
-  Y registeredY;
-  B registeredB;
-  Parameterized<Y> registerParameterizedOfY;
-  
-  @Inject GenericParent() {}
-  
-  @Inject Provider<X> x;
-  @Inject Y y;
-  @Inject B b;
-  @Inject Parameterized<X> parameterizedOfX;
-
-  @Inject
-  void registerX(Provider<X> x) {
-    this.registeredX = x;
-  }
-  @Inject void registerY(Y y) { this.registeredY = y; }
-  @Inject void registerB(B b) { this.registeredB = b; }
-  @Inject void registerParameterizedOfY(Parameterized<Y> parameterizedOfY) {
-    this.registerParameterizedOfY = parameterizedOfY;
-  }
-
-  static class Parameterized<P> {
-    @Inject P p;
-
-    @Inject Parameterized() {}
-  }
-}
diff --git a/javatests/dagger/functional/GenericTest.java b/javatests/dagger/functional/GenericTest.java
deleted file mode 100644
index 3e4a271..0000000
--- a/javatests/dagger/functional/GenericTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
-
-import dagger.functional.sub.Exposed;
-import dagger.functional.sub.PublicSubclass;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class GenericTest {
-
-  @Test public void testGenericComponentCreate() {
-    GenericComponent component = DaggerGenericComponent.create();
-    assertThat(component).isNotNull();
-  }
-  
-  @Test public void testGenericSimpleReferences() {
-    GenericComponent component = DaggerGenericComponent.create();
-    assertThat(component.referencesGeneric().genericA.t).isNotNull();    
-  }
-  
-  @Test public void testGenericDoubleReferences() {
-    GenericComponent component = DaggerGenericComponent.create();
-    GenericDoubleReferences<A> doubleA = component.doubleGenericA();
-    assertThat(doubleA.a).isNotNull();
-    assertThat(doubleA.a2).isNotNull();
-    assertThat(doubleA.t).isNotNull();
-    assertThat(doubleA.t2).isNotNull();
-
-    GenericDoubleReferences<B> doubleB = component.doubleGenericB();
-    assertThat(doubleB.a).isNotNull();
-    assertThat(doubleB.a2).isNotNull();
-    assertThat(doubleB.t).isNotNull();
-    assertThat(doubleB.t2).isNotNull();
-  }
-  
-  @Test public void complexGenerics() {
-    GenericComponent component = DaggerGenericComponent.create();
-    // validate these can be called w/o exceptions.
-    component.complexGenerics();
-  }
-  
-  @Test public void noDepsGenerics() {
-    GenericComponent component = DaggerGenericComponent.create();
-    // validate these can be called w/o exceptions.
-    component.noDepsA();
-    component.noDepsB();
-  }
-  
-  @Test public void boundedGenerics() {
-    BoundedGenericModule expected = new BoundedGenericModule();
-    BoundedGenericComponent component = DaggerBoundedGenericComponent.create();
-    BoundedGenerics<Integer, ArrayList<String>, LinkedList<CharSequence>, Integer, List<Integer>>
-        b1 = component.bounds1();
-    assertEquals(expected.provideInteger(), b1.a);
-    assertEquals(expected.provideArrayListString(), b1.b);
-    assertEquals(expected.provideLinkedListCharSeq(), b1.c);
-    assertEquals(expected.provideInteger(), b1.d);
-    assertEquals(expected.provideListOfInteger(), b1.e);
-
-    BoundedGenerics<Double, LinkedList<String>, LinkedList<Comparable<String>>, Double, Set<Double>>
-        b2 = component.bounds2();
-    assertEquals(expected.provideDouble(), b2.a);
-    assertEquals(expected.provideLinkedListString(), b2.b);
-    assertEquals(expected.provideArrayListOfComparableString(), b2.c);
-    assertEquals(expected.provideDouble(), b2.d);
-    assertEquals(expected.provideSetOfDouble(), b2.e);
-  }
-  
-  @Test public void membersInjections() {
-    GenericComponent component = DaggerGenericComponent.create();
-    GenericChild<A> childA = new GenericChild<A>();
-    component.injectA(childA);
-    assertThat(childA.a).isNotNull();
-    assertThat(childA.b).isNotNull();
-    assertThat(childA.registeredA).isNotNull();
-    assertThat(childA.registeredB).isNotNull();
-    assertThat(childA.registeredT).isNotNull();
-    assertThat(childA.registeredX).isNotNull();
-    assertThat(childA.registeredY).isNotNull();
-    
-    GenericChild<B> childB = new GenericChild<B>();
-    component.injectB(childB);
-    assertThat(childB.a).isNotNull();
-    assertThat(childB.b).isNotNull();
-    assertThat(childB.registeredA).isNotNull();
-    assertThat(childB.registeredB).isNotNull();
-    assertThat(childB.registeredT).isNotNull();
-    assertThat(childB.registeredX).isNotNull();
-    assertThat(childB.registeredY).isNotNull();
-  }
-  
-  @Test public void packagePrivateTypeParameterDependencies() {
-    GenericComponent component = DaggerGenericComponent.create();
-    Exposed exposed = component.exposed();
-    assertThat(exposed.gpp.t).isNotNull();
-    assertThat(exposed.gpp2).isNotNull();
-  }
-  
-  @SuppressWarnings("rawtypes")
-  @Test public void publicSubclassWithPackagePrivateTypeParameterOfSuperclass() {
-    GenericComponent component = DaggerGenericComponent.create();
-    PublicSubclass publicSubclass = component.publicSubclass();
-    assertThat(((Generic)publicSubclass).t).isNotNull();
-  }
-
-  @Test public void singletonScopesAppliesToEachResolvedType() {
-    SingletonGenericComponent component = DaggerSingletonGenericComponent.create();
-    ScopedGeneric<A> a = component.scopedGenericA();
-    assertThat(a).isSameInstanceAs(component.scopedGenericA());
-    assertThat(a.t).isNotNull();
-
-    ScopedGeneric<B> b = component.scopedGenericB();
-    assertThat(b).isSameInstanceAs(component.scopedGenericB());
-    assertThat(b.t).isNotNull();
-
-    assertThat(a).isNotSameInstanceAs(b);
-  }
-
-  @Test // See https://github.com/google/dagger/issues/671
-  public void scopedSimpleGenerics() {
-    SingletonGenericComponent component = DaggerSingletonGenericComponent.create();
-    ScopedSimpleGeneric<A> a = component.scopedSimpleGenericA();
-    assertThat(a).isSameInstanceAs(component.scopedSimpleGenericA());
-
-    ScopedSimpleGeneric<B> b = component.scopedSimpleGenericB();
-    assertThat(b).isSameInstanceAs(component.scopedSimpleGenericB());
-
-    assertThat(a).isNotSameInstanceAs(b);
-  }
-  
-  @Test public void genericModules() {
-    GenericComponent component = DaggerGenericComponent.create();
-    assertThat(component.iterableInt()).containsExactly(1, 2).inOrder();
-    assertThat(component.iterableDouble()).containsExactly(3d, 4d).inOrder();
-  }
-}
diff --git a/javatests/dagger/functional/InjectedThing.java b/javatests/dagger/functional/InjectedThing.java
deleted file mode 100644
index 3041fb0..0000000
--- a/javatests/dagger/functional/InjectedThing.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Lazy;
-import dagger.MembersInjector;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-@SuppressWarnings("unused")
-final class InjectedThing {
-  @Inject byte primitiveByte;
-  @Inject char primitiveChar;
-  @Inject short primitiveShort;
-  @Inject int primitiveInt;
-  @Inject long primitiveLong;
-  @Inject boolean primitiveBoolean;
-  @Inject float primitiveFloat;
-  @Inject double primitiveDouble;
-
-  @Inject Provider<Byte> byteProvider;
-  @Inject Provider<Character> charProvider;
-  @Inject Provider<Short> shortProvider;
-  @Inject Provider<Integer> intProvider;
-  @Inject Provider<Long> longProvider;
-  @Inject Provider<Boolean> booleanProvider;
-  @Inject Provider<Float> floatProvider;
-  @Inject Provider<Double> doubleProvider;
-
-  @Inject Lazy<Byte> lazyByte;
-  @Inject Lazy<Character> lazyChar;
-  @Inject Lazy<Short> lazyShort;
-  @Inject Lazy<Integer> lazyInt;
-  @Inject Lazy<Long> lazyLong;
-  @Inject Lazy<Boolean> lazyBoolean;
-  @Inject Lazy<Float> lazyFloat;
-  @Inject Lazy<Double> lazyDouble;
-
-  @Inject Byte boxedBype;
-  @Inject Character boxedChar;
-  @Inject Short boxedShort;
-  @Inject Integer boxedInt;
-  @Inject Long boxedLong;
-  @Inject Boolean boxedBoolean;
-  @Inject Float boxedFloat;
-  @Inject Double boxedDouble;
-
-  @Inject byte[] byteArray;
-  @Inject char[] charArray;
-  @Inject short[] shortArray;
-  @Inject int[] intArray;
-  @Inject long[] longArray;
-  @Inject boolean[] booleanArray;
-  @Inject float[] floatArray;
-  @Inject double[] doubleArray;
-
-  @Inject Provider<byte[]> byteArrayProvider;
-  @Inject Provider<char[]> charArrayProvider;
-  @Inject Provider<short[]> shortArrayProvider;
-  @Inject Provider<int[]> intArrayProvider;
-  @Inject Provider<long[]> longArrayProvider;
-  @Inject Provider<boolean[]> booleanArrayProvider;
-  @Inject Provider<float[]> floatArrayProvider;
-  @Inject Provider<double[]> doubleArrayProvider;
-
-  @Inject Lazy<byte[]> lazyByteArray;
-  @Inject Lazy<char[]> lazyCharArray;
-  @Inject Lazy<short[]> lazyShortArray;
-  @Inject Lazy<int[]> lazyIntArray;
-  @Inject Lazy<long[]> lazyLongArray;
-  @Inject Lazy<boolean[]> lazyBooleanArray;
-  @Inject Lazy<float[]> lazy;
-  @Inject Lazy<double[]> lazyDoubleArray;
-
-  @Inject Thing thing;
-  @Inject Provider<Thing> thingProvider;
-  @Inject Lazy<Thing> lazyThing;
-  @Inject Provider<Lazy<Thing>> lazyThingProvider;
-  @Inject MembersInjector<Thing> thingMembersInjector;
-
-  @Inject InjectedThing(
-      byte primitiveByte,
-      char primitiveChar,
-      short primitiveShort,
-      int primitiveInt,
-      long primitiveLong,
-      boolean primitiveBoolean,
-      float primitiveFloat,
-      double primitiveDouble,
-
-      Provider<Byte> byteProvider,
-      Provider<Character> charProvider,
-      Provider<Short> shortProvider,
-      Provider<Integer> intProvider,
-      Provider<Long> longProvider,
-      Provider<Boolean> booleanProvider,
-      Provider<Float> floatProvider,
-      Provider<Double> doubleProvider,
-
-      Lazy<Byte> lazyByte,
-      Lazy<Character> lazyChar,
-      Lazy<Short> lazyShort,
-      Lazy<Integer> lazyInt,
-      Lazy<Long> lazyLong,
-      Lazy<Boolean> lazyBoolean,
-      Lazy<Float> lazyFloat,
-      Lazy<Double> lazyDouble,
-
-      Byte boxedBype,
-      Character boxedChar,
-      Short boxedShort,
-      Integer boxedInt,
-      Long boxedLong,
-      Boolean boxedBoolean,
-      Float boxedFloat,
-      Double boxedDouble,
-
-      byte[] byteArray,
-      char[] charArray,
-      short[] shortArray,
-      int[] intArray,
-      long[] longArray,
-      boolean[] booleanArray,
-      float[] floatArray,
-      double[] doubleArray,
-
-      Provider<byte[]> byteArrayProvider,
-      Provider<char[]> charArrayProvider,
-      Provider<short[]> shortArrayProvider,
-      Provider<int[]> intArrayProvider,
-      Provider<long[]> longArrayProvider,
-      Provider<boolean[]> booleanArrayProvider,
-      Provider<float[]> floatArrayProvider,
-      Provider<double[]> doubleArrayProvider,
-
-      Lazy<byte[]> lazyByteArray,
-      Lazy<char[]> lazyCharArray,
-      Lazy<short[]> lazyShortArray,
-      Lazy<int[]> lazyIntArray,
-      Lazy<long[]> lazyLongArray,
-      Lazy<boolean[]> lazyBooleanArray,
-      Lazy<float[]> lazy,
-      Lazy<double[]> lazyDoubleArray,
-
-      Thing thing,
-      Provider<Thing> thingProvider,
-      Lazy<Thing> lazyThing,
-      Provider<Lazy<Thing>> lazyThingProvider,
-      MembersInjector<Thing> thingMembersInjector) {}
-
-  @Inject void primitiveByte(byte primitiveByte) {}
-  @Inject void primitiveChar(char primitiveChar) {}
-  @Inject void primitiveShort(short primitiveShort) {}
-  @Inject void primitiveInt(int primitiveInt) {}
-  @Inject void primitiveLong(long primitiveLong) {}
-  @Inject void primitiveBoolean(boolean primitiveBoolean) {}
-  @Inject void primitiveFloat(float primitiveFloat) {}
-  @Inject void primitiveDouble(double primitiveDouble) {}
-
-  @Inject void byteProvider(Provider<Byte> byteProvider) {}
-  @Inject void charProvider(Provider<Character> charProvider) {}
-  @Inject void shortProvider(Provider<Short> shortProvider) {}
-  @Inject void intProvider(Provider<Integer> intProvider) {}
-  @Inject void longProvider(Provider<Long> longProvider) {}
-  @Inject void booleanProvider(Provider<Boolean> booleanProvider) {}
-  @Inject void floatProvider(Provider<Float> floatProvider) {}
-  @Inject void doubleProvider(Provider<Double> doubleProvider) {}
-
-  @Inject void lazyByte(Lazy<Byte> lazyByte) {}
-  @Inject void lazyChar(Lazy<Character> lazyChar) {}
-  @Inject void lazyShort(Lazy<Short> lazyShort) {}
-  @Inject void lazyInt(Lazy<Integer> lazyInt) {}
-  @Inject void lazyLong(Lazy<Long> lazyLong) {}
-  @Inject void lazyBoolean(Lazy<Boolean> lazyBoolean) {}
-  @Inject void lazyFloat(Lazy<Float> lazyFloat) {}
-  @Inject void lazyDouble(Lazy<Double> lazyDouble) {}
-
-  @Inject void boxedBype(Byte boxedBype) {}
-  @Inject void boxedChar(Character boxedChar) {}
-  @Inject void boxedShort(Short boxedShort) {}
-  @Inject void boxedInt(Integer boxedInt) {}
-  @Inject void boxedLong(Long boxedLong) {}
-  @Inject void boxedBoolean(Boolean boxedBoolean) {}
-  @Inject void boxedFloat(Float boxedFloat) {}
-  @Inject void boxedDouble(Double boxedDouble) {}
-
-  @Inject void byteArray(byte[] byteArray) {}
-  @Inject void charArray(char[] charArray) {}
-  @Inject void shortArray(short[] shortArray) {}
-  @Inject void intArray(int[] intArray) {}
-  @Inject void longArray(long[] longArray) {}
-  @Inject void booleanArray(boolean[] booleanArray) {}
-  @Inject void floatArray(float[] floatArray) {}
-  @Inject void doubleArray(double[] doubleArray) {}
-
-  @Inject void byteArrayProvider(Provider<byte[]> byteArrayProvider) {}
-  @Inject void charArrayProvider(Provider<char[]> charArrayProvider) {}
-  @Inject void shortArrayProvider(Provider<short[]> shortArrayProvider) {}
-  @Inject void intArrayProvider(Provider<int[]> intArrayProvider) {}
-  @Inject void longArrayProvider(Provider<long[]> longArrayProvider) {}
-  @Inject void booleanArrayProvider(Provider<boolean[]> booleanArrayProvider) {}
-  @Inject void floatArrayProvider(Provider<float[]> floatArrayProvider) {}
-  @Inject void doubleArrayProvider(Provider<double[]> doubleArrayProvider) {}
-
-  @Inject void lazyByteArray(Lazy<byte[]> lazyByteArray) {}
-  @Inject void lazyCharArray(Lazy<char[]> lazyCharArray) {}
-  @Inject void lazyShortArray(Lazy<short[]> lazyShortArray) {}
-  @Inject void lazyIntArray(Lazy<int[]> lazyIntArray) {}
-  @Inject void lazyLongArray(Lazy<long[]> lazyLongArray) {}
-  @Inject void lazyBooleanArray(Lazy<boolean[]> lazyBooleanArray) {}
-  @Inject void lazy(Lazy<float[]> lazy) {}
-  @Inject void lazyThingProvider(Provider<Lazy<Thing>> lazyThingProvider) {}
-  @Inject void lazyDoubleArray(Lazy<double[]> lazyDoubleArray) {}
-
-  @Inject void thing(Thing thing) {}
-  @Inject void thingProvider(Provider<Thing> thingProvider) {}
-  @Inject void lazyThing(Lazy<Thing> lazyThing) {}
-  @Inject void thingMembersInjector(MembersInjector<Thing> thingMembersInjector) {}
-}
diff --git a/javatests/dagger/functional/Injector.java b/javatests/dagger/functional/Injector.java
deleted file mode 100644
index d001f93..0000000
--- a/javatests/dagger/functional/Injector.java
+++ /dev/null
@@ -1,33 +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.functional;
-
-import dagger.Lazy;
-import dagger.MembersInjector;
-import javax.inject.Provider;
-
-/**
- * A simple interface that exercises all forms of injection for a given type.
- */
-interface Injector<T> {
-  T instance();
-  Provider<T> provider();
-  Lazy<T> lazy();
-  MembersInjector<T> membersInjector();
-  void injectMembers(T t);
-  T injectMembersAndReturn(T t);
-}
diff --git a/javatests/dagger/functional/LazyMaps.java b/javatests/dagger/functional/LazyMaps.java
deleted file mode 100644
index eeb1368..0000000
--- a/javatests/dagger/functional/LazyMaps.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional;
-
-import dagger.Component;
-import dagger.Lazy;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.StringKey;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-/**
- * Bindings that use {@code Lazy<T>} as the value in a multibound map. A regression was uncovered
- * when using {@code MapType.valuesAreFrameworkType()}, which treats {@link Lazy} as a framework
- * type and incorrectly suggested {@link dagger.internal.MapProviderFactory} for a {@code Map<K,
- * Lazy<V>>} instead of a plain {@link dagger.internal.MapFactory}. See b/65084589.
- */
-class LazyMaps {
-  @Module
-  abstract static class TestModule {
-    @Provides
-    @Singleton
-    static AtomicInteger provideAtomicInteger() {
-      return new AtomicInteger();
-    }
-
-    @Provides
-    static String provideString(AtomicInteger atomicInteger) {
-      return "value-" + atomicInteger.incrementAndGet();
-    }
-
-    @Provides
-    @IntoMap
-    @StringKey("key")
-    static Lazy<String> mapContribution(Lazy<String> lazy) {
-      return lazy;
-    }
-
-    /* TODO(b/65118638) Replace once @Binds @IntoMap Lazy<T> methods work properly.
-    @Binds
-    @IntoMap
-    @StringKey("binds-key")
-    abstract Lazy<String> mapContributionAsBinds(Lazy<String> lazy);
-    */
-  }
-
-  @Singleton
-  @Component(modules = TestModule.class)
-  interface TestComponent {
-    Map<String, Lazy<String>> mapOfLazy();
-
-    Map<String, Provider<Lazy<String>>> mapOfProviderOfLazy();
-
-    Provider<Map<String, Lazy<String>>> providerForMapOfLazy();
-
-    Provider<Map<String, Provider<Lazy<String>>>> providerForMapOfProviderOfLazy();
-  }
-}
diff --git a/javatests/dagger/functional/LazyMapsTest.java b/javatests/dagger/functional/LazyMapsTest.java
deleted file mode 100644
index a441653..0000000
--- a/javatests/dagger/functional/LazyMapsTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Lazy;
-import dagger.functional.LazyMaps.TestComponent;
-import java.util.Map;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link LazyMaps}. */
-@RunWith(JUnit4.class)
-public class LazyMapsTest {
-  @Test
-  public void mapOfLazies() {
-    TestComponent component = DaggerLazyMaps_TestComponent.create();
-    Map<String, Lazy<String>> laziesMap = component.mapOfLazy();
-
-    String firstGet = laziesMap.get("key").get();
-    assertThat(firstGet).isEqualTo("value-1");
-    assertThat(firstGet).isSameInstanceAs(laziesMap.get("key").get());
-
-    assertThat(component.mapOfLazy().get("key").get()).isEqualTo("value-2");
-  }
-
-  @Test
-  public void mapOfProviderOfLaziesReturnsDifferentLazy() {
-    TestComponent component = DaggerLazyMaps_TestComponent.create();
-    Map<String, Provider<Lazy<String>>> providersOfLaziesMap = component.mapOfProviderOfLazy();
-
-    assertThat(providersOfLaziesMap.get("key").get().get())
-        .isNotEqualTo(providersOfLaziesMap.get("key").get().get());
-  }
-}
diff --git a/javatests/dagger/functional/ModuleCycles.java b/javatests/dagger/functional/ModuleCycles.java
deleted file mode 100644
index 9df6685..0000000
--- a/javatests/dagger/functional/ModuleCycles.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-
-final class ModuleCycles {
-  @Module(includes = ModuleB.class)
-  interface ModuleA {}
-
-  @Module(includes = ModuleA.class)
-  interface ModuleB {}
-
-  @Component(modules = ModuleA.class)
-  interface CycleComponent {}
-}
diff --git a/javatests/dagger/functional/ModuleIncludesCollectedFromModuleSuperclasses.java b/javatests/dagger/functional/ModuleIncludesCollectedFromModuleSuperclasses.java
deleted file mode 100644
index fb18b6d..0000000
--- a/javatests/dagger/functional/ModuleIncludesCollectedFromModuleSuperclasses.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * This tests that @Module.includes are traversed for supertypes of a module.
- */
-final class ModuleIncludesCollectedFromModuleSuperclasses {
-  @Component(modules = TopLevelModule.class)
-  interface C {
-    Foo<String> foo();
-    int includedInTopLevelModule();
-    String includedFromModuleInheritance();
-  }
-
-  @Module(includes = IncludedTopLevel.class)
-  static class TopLevelModule extends FooModule<String> {}
-
-  static class Foo<T> {}
-
-  @Module(includes = IncludedFromModuleInheritance.class)
-  abstract static class FooModule<T> extends FooCreator {
-    @Provides Foo<T> fooOfT() {
-      return createFoo();
-    }
-  }
-
-  static class FooCreator {
-    <T> Foo<T> createFoo() {
-      return new Foo<T>();
-    }
-  }
-
-  @Module
-  static class IncludedTopLevel {
-    @Provides int i() {
-      return 123;
-    }
-  }
-
-  @Module
-  static class IncludedFromModuleInheritance {
-    @Provides String inheritedProvision() {
-      return "inherited";
-    }
-  }
-}
diff --git a/javatests/dagger/functional/ModuleWithConflictingNames.java b/javatests/dagger/functional/ModuleWithConflictingNames.java
deleted file mode 100644
index 43dd58e..0000000
--- a/javatests/dagger/functional/ModuleWithConflictingNames.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/**
- * Module with bindings that might result in generated factories with conflicting field and
- * parameter names.
- */
-@Module
-final class ModuleWithConflictingNames {
-  @Provides
-  static Object object(int foo, Provider<String> fooProvider) {
-    return foo + fooProvider.get();
-  }
-
-  /**
-   * A class that might result in a generated factory with conflicting field and parameter names.
-   */
-  static class InjectedClassWithConflictingNames {
-    final int foo;
-    final Provider<String> fooProvider;
-
-    @Inject
-    InjectedClassWithConflictingNames(int foo, Provider<String> fooProvider) {
-      this.foo = foo;
-      this.fooProvider = fooProvider;
-    }
-  }
-}
diff --git a/javatests/dagger/functional/MultibindingComponent.java b/javatests/dagger/functional/MultibindingComponent.java
deleted file mode 100644
index 60ed5cf..0000000
--- a/javatests/dagger/functional/MultibindingComponent.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-import dagger.functional.sub.ContributionsModule;
-import dagger.multibindings.StringKey;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Named;
-import javax.inject.Provider;
-
-@Component(
-  modules = {MultibindingModule.class, MultibindsModule.class, ContributionsModule.class},
-  dependencies = MultibindingDependency.class
-)
-interface MultibindingComponent {
-  Map<String, String> map();
-  Map<String, String[]> mapOfArrays();
-  Map<String, Provider<String>> mapOfProviders();
-  Set<String> mapKeys();
-  Collection<String> mapValues();
-  Set<Integer> set();
-  Map<NestedAnnotationContainer.NestedWrappedKey, String> nestedKeyMap();
-  Map<Class<? extends Number>, String> numberClassKeyMap();
-  Map<Class<?>, String> classKeyMap();
-  Map<Long, String> longKeyMap();
-  Map<Integer, String> integerKeyMap();
-  Map<Short, String> shortKeyMap();
-  Map<Byte, String> byteKeyMap();
-  Map<Boolean, String> booleanKeyMap();
-  Map<Character, String> characterKeyMap();
-  Map<StringKey, String> unwrappedAnnotationKeyMap();
-  Map<WrappedAnnotationKey, String> wrappedAnnotationKeyMap();
-  @Named("complexQualifier") Set<String> complexQualifierStringSet();
-  Set<Object> emptySet();
-
-  @Named("complexQualifier")
-  Set<Object> emptyQualifiedSet();
-
-  Map<String, Object> emptyMap();
-
-  @Named("complexQualifier")
-  Map<String, Object> emptyQualifiedMap();
-
-  Set<CharSequence> maybeEmptySet();
-
-  @Named("complexQualifier")
-  Set<CharSequence> maybeEmptyQualifiedSet();
-
-  Map<String, CharSequence> maybeEmptyMap();
-
-  @Named("complexQualifier")
-  Map<String, CharSequence> maybeEmptyQualifiedMap();
-}
diff --git a/javatests/dagger/functional/MultibindingDependency.java b/javatests/dagger/functional/MultibindingDependency.java
deleted file mode 100644
index 4240051..0000000
--- a/javatests/dagger/functional/MultibindingDependency.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-interface MultibindingDependency {
-  double doubleDependency();
-}
diff --git a/javatests/dagger/functional/MultibindingModule.java b/javatests/dagger/functional/MultibindingModule.java
deleted file mode 100644
index e167628..0000000
--- a/javatests/dagger/functional/MultibindingModule.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.multibindings.LongKey;
-import dagger.multibindings.StringKey;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Named;
-import javax.inject.Provider;
-
-@Module
-class MultibindingModule {
-  @Provides
-  @IntoMap
-  @StringKey("foo")
-  static String provideFooKey(@SuppressWarnings("unused") double doubleDependency) {
-    return "foo value";
-  }
-
-  @Provides
-  @IntoMap
-  @StringKey("bar")
-  static String provideBarKey() {
-    return "bar value";
-  }
-
-  @Provides
-  @IntoMap
-  @StringKey("foo")
-  static String[] provideFooArrayValue(@SuppressWarnings("unused") double doubleDependency) {
-    return new String[] {"foo1", "foo2"};
-  }
-
-  @Provides
-  @IntoMap
-  @StringKey("bar")
-  static String[] provideBarArrayValue() {
-    return new String[] {"bar1", "bar2"};
-  }
-
-  @Provides
-  @IntoSet
-  static int provideFiveToSet() {
-    return 5;
-  }
-
-  @Provides
-  @IntoSet
-  static int provideSixToSet() {
-    return 6;
-  }
-
-  @Provides
-  @ElementsIntoSet
-  static Set<Integer> provideElementsIntoSet() {
-    Set<Integer> set = new HashSet<>();
-    set.add(-101);
-    set.add(-102);
-    return set;
-  }
-
-  @Provides
-  static Set<String> provideMapKeys(Map<String, Provider<String>> map) {
-    return map.keySet();
-  }
-
-  @Provides
-  static Collection<String> provideMapValues(Map<String, String> map) {
-    return map.values();
-  }
-
-  @Provides
-  @IntoMap
-  @NestedAnnotationContainer.NestedWrappedKey(Integer.class)
-  static String valueForInteger() {
-    return "integer";
-  }
-
-  @Provides
-  @IntoMap
-  @NestedAnnotationContainer.NestedWrappedKey(Long.class)
-  static String valueForLong() {
-    return "long";
-  }
-
-  @Provides
-  @IntoMap
-  @ClassKey(Integer.class)
-  static String valueForClassInteger() {
-    return "integer";
-  }
-
-  @Provides
-  @IntoMap
-  @ClassKey(Long.class)
-  static String valueForClassLong() {
-    return "long";
-  }
-
-  @Provides
-  @IntoMap
-  @NumberClassKey(BigDecimal.class)
-  static String valueForNumberClassBigDecimal() {
-    return "bigdecimal";
-  }
-
-  @Provides
-  @IntoMap
-  @NumberClassKey(BigInteger.class)
-  static String valueForNumberClassBigInteger() {
-    return "biginteger";
-  }
-
-  @Provides
-  @IntoMap
-  @LongKey(100)
-  static String valueFor100Long() {
-    return "100 long";
-  }
-
-  @Provides
-  @IntoMap
-  @IntKey(100)
-  static String valueFor100Int() {
-    return "100 int";
-  }
-
-  @Provides
-  @IntoMap
-  @ShortKey(100)
-  static String valueFor100Short() {
-    return "100 short";
-  }
-
-  @Provides
-  @IntoMap
-  @ByteKey(100)
-  static String valueFor100Byte() {
-    return "100 byte";
-  }
-
-  @Provides
-  @IntoMap
-  @BooleanKey(true)
-  static String valueForTrue() {
-    return "true";
-  }
-
-  @Provides
-  @IntoMap
-  @CharKey('a')
-  static String valueForA() {
-    return "a char";
-  }
-
-  @Provides
-  @IntoMap
-  @CharKey('\n')
-  static String valueForNewline() {
-    return "newline char";
-  }
-
-  @Provides
-  @IntoMap
-  @UnwrappedAnnotationKey(@StringKey("foo\n"))
-  static String valueForUnwrappedAnnotationKeyFoo() {
-    return "foo annotation";
-  }
-
-  @Provides
-  @IntoMap
-  @WrappedAnnotationKey(
-    value = @StringKey("foo"),
-    integers = {1, 2, 3},
-    annotations = {},
-    classes = {Long.class, Integer.class}
-  )
-  static String valueForWrappedAnnotationKeyFoo() {
-    return "wrapped foo annotation";
-  }
-
-  @Provides
-  @IntoSet
-  @Named("complexQualifier")
-  static String valueForComplexQualifierSet() {
-    return "foo";
-  }
-
-  @Provides
-  @IntoSet
-  static CharSequence setContribution() {
-    return "foo";
-  }
-
-  @Provides
-  @IntoSet
-  @Named("complexQualifier")
-  static CharSequence qualifiedSetContribution() {
-    return "qualified foo";
-  }
-
-  @Provides
-  @IntoMap
-  @StringKey("key")
-  static CharSequence mapContribution() {
-    return "foo value";
-  }
-
-  @Provides
-  @IntoMap
-  @Named("complexQualifier")
-  @StringKey("key")
-  static CharSequence qualifiedMapContribution() {
-    return "qualified foo value";
-  }
-}
diff --git a/javatests/dagger/functional/MultibindingTest.java b/javatests/dagger/functional/MultibindingTest.java
deleted file mode 100644
index d99e46d..0000000
--- a/javatests/dagger/functional/MultibindingTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.auto.value.AutoAnnotation;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.StringKey;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Map;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link MultibindingComponent}. */
-@RunWith(JUnit4.class)
-public class MultibindingTest {
-
-  private final MultibindingComponent multibindingComponent =
-      DaggerMultibindingComponent.builder().multibindingDependency(() -> 0.0).build();
-
-  @Test public void map() {
-    Map<String, String> map = multibindingComponent.map();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsEntry("foo", "foo value");
-    assertThat(map).containsEntry("bar", "bar value");
-  }
-
-  @Test public void mapOfArrays() {
-    Map<String, String[]> map = multibindingComponent.mapOfArrays();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsKey("foo");
-    assertThat(map.get("foo")).asList().containsExactly("foo1", "foo2").inOrder();
-    assertThat(map).containsKey("bar");
-    assertThat(map.get("bar")).asList().containsExactly("bar1", "bar2").inOrder();
-  }
-
-  @Test public void mapOfProviders() {
-    Map<String, Provider<String>> mapOfProviders = multibindingComponent.mapOfProviders();
-    assertThat(mapOfProviders).hasSize(2);
-    assertThat(mapOfProviders.get("foo").get()).isEqualTo("foo value");
-    assertThat(mapOfProviders.get("bar").get()).isEqualTo("bar value");
-  }
-
-  @Test public void mapKeysAndValues() {
-    assertThat(multibindingComponent.mapKeys())
-        .containsExactly("foo", "bar");
-    assertThat(multibindingComponent.mapValues())
-        .containsExactly("foo value", "bar value");
-  }
-
-  @Test public void nestedKeyMap() {
-    assertThat(multibindingComponent.nestedKeyMap())
-        .containsExactly(
-            nestedWrappedKey(Integer.class), "integer", nestedWrappedKey(Long.class), "long");
-  }
-
-  @Test
-  public void unwrappedAnnotationKeyMap() {
-    assertThat(multibindingComponent.unwrappedAnnotationKeyMap())
-        .containsExactly(testStringKey("foo\n"), "foo annotation");
-  }
-
-  @Test
-  public void wrappedAnnotationKeyMap() {
-    @SuppressWarnings("unchecked")
-    Class<? extends Number>[] classes = new Class[] {Long.class, Integer.class};
-    assertThat(multibindingComponent.wrappedAnnotationKeyMap())
-        .containsExactly(
-            testWrappedAnnotationKey(
-                testStringKey("foo"), new int[] {1, 2, 3}, new ClassKey[] {}, classes),
-            "wrapped foo annotation");
-  }
-
-  @Test
-  public void booleanKeyMap() {
-    assertThat(multibindingComponent.booleanKeyMap()).containsExactly(true, "true");
-  }
-
-  @Test
-  public void byteKeyMap() {
-    assertThat(multibindingComponent.byteKeyMap()).containsExactly((byte) 100, "100 byte");
-  }
-
-  @Test
-  public void charKeyMap() {
-    assertThat(multibindingComponent.characterKeyMap())
-        .containsExactly('a', "a char", '\n', "newline char");
-  }
-
-  @Test
-  public void classKeyMap() {
-    assertThat(multibindingComponent.classKeyMap())
-        .containsExactly(Integer.class, "integer", Long.class, "long");
-  }
-
-  @Test
-  public void numberClassKeyMap() {
-    assertThat(multibindingComponent.numberClassKeyMap())
-        .containsExactly(BigDecimal.class, "bigdecimal", BigInteger.class, "biginteger");
-  }
-
-  @Test
-  public void intKeyMap() {
-    assertThat(multibindingComponent.integerKeyMap()).containsExactly(100, "100 int");
-  }
-
-  @Test
-  public void longKeyMap() {
-    assertThat(multibindingComponent.longKeyMap()).containsExactly((long) 100, "100 long");
-  }
-
-  @Test
-  public void shortKeyMap() {
-    assertThat(multibindingComponent.shortKeyMap()).containsExactly((short) 100, "100 short");
-  }
-
-  @Test public void setBindings() {
-    assertThat(multibindingComponent.set())
-        .containsExactly(-90, -17, -1, 5, 6, 832, 1742, -101, -102);
-  }
-
-  @Test
-  public void complexQualifierSet() {
-    assertThat(multibindingComponent.complexQualifierStringSet()).containsExactly("foo");
-  }
-
-  @Test
-  public void emptySet() {
-    assertThat(multibindingComponent.emptySet()).isEmpty();
-  }
-
-  @Test
-  public void emptyQualifiedSet() {
-    assertThat(multibindingComponent.emptyQualifiedSet()).isEmpty();
-  }
-
-  @Test
-  public void emptyMap() {
-    assertThat(multibindingComponent.emptyMap()).isEmpty();
-  }
-
-  @Test
-  public void emptyQualifiedMap() {
-    assertThat(multibindingComponent.emptyQualifiedMap()).isEmpty();
-  }
-
-  @Test
-  public void maybeEmptySet() {
-    assertThat(multibindingComponent.maybeEmptySet()).containsExactly("foo");
-  }
-
-  @Test
-  public void maybeEmptyQualifiedSet() {
-    assertThat(multibindingComponent.maybeEmptyQualifiedSet()).containsExactly("qualified foo");
-  }
-
-  @Test
-  public void maybeEmptyMap() {
-    assertThat(multibindingComponent.maybeEmptyMap()).containsEntry("key", "foo value");
-  }
-
-  @Test
-  public void maybeEmptyQualifiedMap() {
-    assertThat(multibindingComponent.maybeEmptyQualifiedMap())
-        .containsEntry("key", "qualified foo value");
-  }
-
-  @AutoAnnotation
-  static StringKey testStringKey(String value) {
-    return new AutoAnnotation_MultibindingTest_testStringKey(value);
-  }
-
-  @AutoAnnotation
-  static NestedAnnotationContainer.NestedWrappedKey nestedWrappedKey(Class<?> value) {
-    return new AutoAnnotation_MultibindingTest_nestedWrappedKey(value);
-  }
-
-  @AutoAnnotation
-  static WrappedAnnotationKey testWrappedAnnotationKey(
-      StringKey value, int[] integers, ClassKey[] annotations, Class<? extends Number>[] classes) {
-    return new AutoAnnotation_MultibindingTest_testWrappedAnnotationKey(
-        value, integers, annotations, classes);
-  }
-}
diff --git a/javatests/dagger/functional/MultibindsModule.java b/javatests/dagger/functional/MultibindsModule.java
deleted file mode 100644
index 65ba7c8..0000000
--- a/javatests/dagger/functional/MultibindsModule.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Module;
-import dagger.multibindings.Multibinds;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Named;
-
-/**
- * A module that uses {@link Multibinds @Multibinds}-annotated abstract methods to declare
- * multibindings.
- */
-@Module
-abstract class MultibindsModule {
-
-  @Multibinds
-  abstract Set<Object> emptySet();
-
-  @Multibinds
-  abstract Map<String, Object> emptyMap();
-
-  @Multibinds
-  abstract Set<CharSequence> set();
-
-  @Multibinds
-  abstract Map<String, CharSequence> map();
-
-  @Multibinds
-  @Named("complexQualifier")
-  abstract Set<Object> emptyQualifiedSet();
-
-  @Multibinds
-  @Named("complexQualifier")
-  abstract Map<String, Object> emptyQualifiedMap();
-
-  @Multibinds
-  @Named("complexQualifier")
-  abstract Set<CharSequence> qualifiedSet();
-
-  @Multibinds
-  @Named("complexQualifier")
-  abstract Map<String, CharSequence> qualifiedMap();
-}
diff --git a/javatests/dagger/functional/NeedsFactory.java b/javatests/dagger/functional/NeedsFactory.java
deleted file mode 100644
index 2ea01ec..0000000
--- a/javatests/dagger/functional/NeedsFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import com.google.auto.factory.AutoFactory;
-import javax.inject.Inject;
-
-class NeedsFactory {
-  @Inject
-  NeedsFactory(@SuppressWarnings("unused") NeedsFactory_SomethingFactory somethingFactory) {}
-
-  @AutoFactory
-  static class Something {}
-}
-
diff --git a/javatests/dagger/functional/NeedsProviderOfFactory.java b/javatests/dagger/functional/NeedsProviderOfFactory.java
deleted file mode 100644
index efbd73d..0000000
--- a/javatests/dagger/functional/NeedsProviderOfFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import com.google.auto.factory.AutoFactory;
-import dagger.Component;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-// b/73455487
-class NeedsProviderOfFactory {
-  static class InjectsProviderOfFactory {
-    @Inject
-    InjectsProviderOfFactory(
-        Provider<NeedsProviderOfFactory_SomethingFactory> provider) {}
-  }
-
-  @Component
-  interface ExposesFactoryAsProvider {
-    InjectsProviderOfFactory injectsProviderOfFactory();
-  }
-
-  @AutoFactory
-  static class Something {}
-}
diff --git a/javatests/dagger/functional/NestedAnnotationContainer.java b/javatests/dagger/functional/NestedAnnotationContainer.java
deleted file mode 100644
index a2b61fa..0000000
--- a/javatests/dagger/functional/NestedAnnotationContainer.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-public final class NestedAnnotationContainer {
-
-  @MapKey(unwrapValue = false)
-  @interface NestedWrappedKey {
-    Class<?> value();
-  }
-}
diff --git a/javatests/dagger/functional/NestedTest.java b/javatests/dagger/functional/NestedTest.java
deleted file mode 100644
index c1e21b2..0000000
--- a/javatests/dagger/functional/NestedTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NestedTest {
-  @Test public void nestedFoo() {
-    OuterClassFoo.NestedComponent nestedFoo = DaggerOuterClassFoo_NestedComponent.create();
-    assertThat(nestedFoo.thing()).isNotNull();
-  }
-
-  @Test public void nestedBar() {
-    OuterClassBar.NestedComponent nestedBar = DaggerOuterClassBar_NestedComponent.create();
-    assertThat(nestedBar.injectedThing()).isNotNull();
-  }
-}
diff --git a/javatests/dagger/functional/NonComponentDependencyComponent.java b/javatests/dagger/functional/NonComponentDependencyComponent.java
deleted file mode 100644
index ee679fa..0000000
--- a/javatests/dagger/functional/NonComponentDependencyComponent.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-import dagger.functional.sub.OtherThing;
-import javax.inject.Inject;
-
-@Component(dependencies = {NonComponentDependencyComponent.ThingComponent.class})
-interface NonComponentDependencyComponent {
-  ThingTwo thingTwo();
-
-  static class ThingTwo {
-    @SuppressWarnings("unused")
-    @Inject
-    ThingTwo(
-        Thing thing,
-        NonComponentDependencyComponent nonComponentDependencyComponent,
-        NonComponentDependencyComponent.ThingComponent thingComponent) {}
-  }
-
-  // A non-component interface which this interface depends upon.
-  interface ThingComponent {
-    Thing thing();
-  }
-
-  // The implementation for that interface.
-  static class ThingComponentImpl implements ThingComponent {
-    @Override
-    public Thing thing() {
-      return new Thing(new OtherThing(1));
-    }
-  }
-}
diff --git a/javatests/dagger/functional/NonComponentDependencyTest.java b/javatests/dagger/functional/NonComponentDependencyTest.java
deleted file mode 100644
index 436183f..0000000
--- a/javatests/dagger/functional/NonComponentDependencyTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NonComponentDependencyTest {
-  @Test public void testThing() {
-    NonComponentDependencyComponent component =
-        DaggerNonComponentDependencyComponent.builder()
-            .thingComponent(new NonComponentDependencyComponent.ThingComponentImpl())
-            .build();
-    assertThat(component).isNotNull();
-    assertThat(component.thingTwo()).isNotNull();
-  }
-}
diff --git a/javatests/dagger/functional/NullableModule.java b/javatests/dagger/functional/NullableModule.java
deleted file mode 100644
index 406024f..0000000
--- a/javatests/dagger/functional/NullableModule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class NullableModule {
-  /**
-   * A {@code Nullable} that isn't {@link javax.annotation.Nullable}, to ensure that Dagger can be
-   * built without depending on JSR-305.
-   */
-  @interface Nullable {}
-
-  @Provides
-  @Nullable
-  static Object nullObject() {
-    return null;
-  }
-}
diff --git a/javatests/dagger/functional/NumberClassKey.java b/javatests/dagger/functional/NumberClassKey.java
deleted file mode 100644
index 5909a9f..0000000
--- a/javatests/dagger/functional/NumberClassKey.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-@MapKey(unwrapValue = true)
-@interface NumberClassKey {
-  Class<? extends Number> value();
-}
diff --git a/javatests/dagger/functional/OuterClassBar.java b/javatests/dagger/functional/OuterClassBar.java
deleted file mode 100644
index b455595..0000000
--- a/javatests/dagger/functional/OuterClassBar.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-
-final class OuterClassBar {
-  @Component(modules = PrimitivesModule.class)
-  interface NestedComponent {
-    InjectedThing injectedThing();
-  }
-}
diff --git a/javatests/dagger/functional/OuterClassFoo.java b/javatests/dagger/functional/OuterClassFoo.java
deleted file mode 100644
index 213bd80..0000000
--- a/javatests/dagger/functional/OuterClassFoo.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-
-final class OuterClassFoo {
-  @Component(modules = PrimitivesModule.class)
-  interface NestedComponent {
-    Thing thing();
-  }
-}
diff --git a/javatests/dagger/functional/ParentModule.java b/javatests/dagger/functional/ParentModule.java
deleted file mode 100644
index 8bd4fea..0000000
--- a/javatests/dagger/functional/ParentModule.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-@Module
-abstract class ParentModule<A extends Number & Comparable<A>, B, C extends Iterable<A>> {
-  @Provides Iterable<A> provideIterableOfAWithC(A a, C c) {
-    List<A> list = new ArrayList<>();
-    list.add(a);
-    for (A elt : c) {
-      list.add(elt);
-    }
-    return list;
-  }
-
-  @Provides static char provideNonGenericBindingInParameterizedModule() {
-    return 'c';
-  }
-
-  @Provides
-  static List<Set<String>> provideStaticGenericTypeWithNoTypeParametersInParameterizedModule() {
-    return new ArrayList<>();
-  }
-}
diff --git a/javatests/dagger/functional/PrimitivesModule.java b/javatests/dagger/functional/PrimitivesModule.java
deleted file mode 100644
index 7b7203b..0000000
--- a/javatests/dagger/functional/PrimitivesModule.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class PrimitivesModule {
-  static final byte BOUND_BYTE = -41;
-  static final char BOUND_CHAR = 'g';
-  static final short BOUND_SHORT = 21840;
-  static final int BOUND_INT = 1894833693;
-  static final long BOUND_LONG = -4369839828653523584L;
-  static final boolean BOUND_BOOLEAN = true;
-  static final float BOUND_FLOAT = (float) 0.9964542;
-  static final double BOUND_DOUBLE = 0.12681322049667765;
-
-  /*
-   * While we can't ensure that these constants stay constant, this is a test so we're just going to
-   * keep our fingers crossed that we're not going to be jerks.
-   */
-  static final byte[] BOUND_BYTE_ARRAY =  {1, 2, 3};
-  static final char[] BOUND_CHAR_ARRAY = {'g', 'a', 'k'};
-  static final short[] BOUND_SHORT_ARRAY = {2, 4};
-  static final int[] BOUND_INT_ARRAY = {3, 1, 2};
-  static final long[] BOUND_LONG_ARRAY = {1, 1, 2, 3, 5};
-  static final boolean[] BOUND_BOOLEAN_ARRAY = {false, true, false, false};
-  static final float[] BOUND_FLOAT_ARRAY = {(float) 0.1, (float) 0.01, (float) 0.001};
-  static final double[] BOUND_DOUBLE_ARRAY = {0.2, 0.02, 0.002};
-
-  @Provides static byte provideByte() {
-    return BOUND_BYTE;
-  }
-
-  @Provides static char provideChar() {
-    return BOUND_CHAR;
-  }
-
-  @Provides static short provideShort() {
-    return BOUND_SHORT;
-  }
-
-  @Provides static int provideInt() {
-    return BOUND_INT;
-  }
-
-  @Provides static long provideLong() {
-    return BOUND_LONG;
-  }
-
-  @Provides static boolean provideBoolean() {
-    return BOUND_BOOLEAN;
-  }
-
-  @Provides static float provideFloat() {
-    return BOUND_FLOAT;
-  }
-
-  @Provides static double boundDouble() {
-    return BOUND_DOUBLE;
-  }
-
-  @Provides static byte[] provideByteArray() {
-    return BOUND_BYTE_ARRAY;
-  }
-
-  @Provides static char[] provideCharArray() {
-    return BOUND_CHAR_ARRAY;
-  }
-
-  @Provides static short[] provideShortArray() {
-    return BOUND_SHORT_ARRAY;
-  }
-
-  @Provides static int[] provideIntArray() {
-    return BOUND_INT_ARRAY;
-  }
-
-  @Provides static long[] provideLongArray() {
-    return BOUND_LONG_ARRAY;
-  }
-
-  @Provides static boolean[] provideBooleanArray() {
-    return BOUND_BOOLEAN_ARRAY;
-  }
-
-  @Provides static float[] provideFloatArray() {
-    return BOUND_FLOAT_ARRAY;
-  }
-
-  @Provides static double[] boundDoubleArray() {
-    return BOUND_DOUBLE_ARRAY;
-  }
-}
diff --git a/javatests/dagger/functional/ReferencesGeneric.java b/javatests/dagger/functional/ReferencesGeneric.java
deleted file mode 100644
index c83dbcc..0000000
--- a/javatests/dagger/functional/ReferencesGeneric.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-class ReferencesGeneric {
-  final Generic<A> genericA;
-  
-  @Inject ReferencesGeneric(Generic<A> genericA) {
-    this.genericA = genericA;
-  }
-}
diff --git a/javatests/dagger/functional/ReusableTest.java b/javatests/dagger/functional/ReusableTest.java
deleted file mode 100644
index 221b288..0000000
--- a/javatests/dagger/functional/ReusableTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.ComponentWithReusableBindings.ChildOne;
-import dagger.functional.ComponentWithReusableBindings.ChildTwo;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ReusableTest {
-  @Test
-  public void testReusable() {
-    ComponentWithReusableBindings parent = DaggerComponentWithReusableBindings.create();
-    ChildOne childOne = parent.childOne();
-    ChildTwo childTwo = parent.childTwo();
-
-    Object reusableInParent = parent.reusableInParent();
-    assertThat(parent.reusableInParent()).isSameInstanceAs(reusableInParent);
-    assertThat(childOne.reusableInParent()).isSameInstanceAs(reusableInParent);
-    assertThat(childTwo.reusableInParent()).isSameInstanceAs(reusableInParent);
-
-    Object reusableFromChildOne = childOne.reusableInChild();
-    assertThat(childOne.reusableInChild()).isSameInstanceAs(reusableFromChildOne);
-
-    Object reusableFromChildTwo = childTwo.reusableInChild();
-    assertThat(childTwo.reusableInChild()).isSameInstanceAs(reusableFromChildTwo);
-
-    assertThat(reusableFromChildTwo).isNotSameInstanceAs(reusableFromChildOne);
-  }
-}
diff --git a/javatests/dagger/functional/ScopedGeneric.java b/javatests/dagger/functional/ScopedGeneric.java
deleted file mode 100644
index da7e157..0000000
--- a/javatests/dagger/functional/ScopedGeneric.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-class ScopedGeneric<T> { 
-  final T t;  
-  @Inject ScopedGeneric(T t) {
-    this.t = t;
-  }  
-}
diff --git a/javatests/dagger/functional/ScopedSimpleGeneric.java b/javatests/dagger/functional/ScopedSimpleGeneric.java
deleted file mode 100644
index 8e48eba..0000000
--- a/javatests/dagger/functional/ScopedSimpleGeneric.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * An {@link Inject Inject}ed generic class with no dependencies. Its factory class will have a
- * generic {@code create()} method returning an object whose type parameters cannot be inferred from
- * its arguments. Since it's scoped, the initialization of its field in a generated component must
- * use a raw {@link javax.inject.Provider} in order to allow casting from {@code
- * Provider<ScopedSimpleGeneric<Object>>} to {@code Provider<ScopedSimpleGeneric<Foo>>}.
- */
-@Singleton
-class ScopedSimpleGeneric<T> {
-  @Inject
-  ScopedSimpleGeneric() {}
-}
diff --git a/javatests/dagger/functional/ShortKey.java b/javatests/dagger/functional/ShortKey.java
deleted file mode 100644
index 3d81d8f..0000000
--- a/javatests/dagger/functional/ShortKey.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-
-@MapKey(unwrapValue = true)
-@interface ShortKey {
-  short value();
-}
diff --git a/javatests/dagger/functional/SingletonGenericComponent.java b/javatests/dagger/functional/SingletonGenericComponent.java
deleted file mode 100644
index d9823cd..0000000
--- a/javatests/dagger/functional/SingletonGenericComponent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.Component;
-import javax.inject.Singleton;
-
-@Singleton
-@Component
-interface SingletonGenericComponent {
-  
-  ScopedGeneric<A> scopedGenericA();
-
-  ScopedGeneric<B> scopedGenericB();
-  
-  ScopedSimpleGeneric<A> scopedSimpleGenericA();
-
-  ScopedSimpleGeneric<B> scopedSimpleGenericB();
-
-}
diff --git a/javatests/dagger/functional/SomeQualifier.java b/javatests/dagger/functional/SomeQualifier.java
deleted file mode 100644
index 126398c..0000000
--- a/javatests/dagger/functional/SomeQualifier.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-@Documented
-@Retention(RUNTIME)
-@Qualifier
-public @interface SomeQualifier {}
diff --git a/javatests/dagger/functional/Thing.java b/javatests/dagger/functional/Thing.java
deleted file mode 100644
index b51b96a..0000000
--- a/javatests/dagger/functional/Thing.java
+++ /dev/null
@@ -1,24 +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.functional;
-
-import dagger.functional.sub.OtherThing;
-import javax.inject.Inject;
-
-final class Thing {
-  @Inject Thing(@SuppressWarnings("unused") OtherThing unused) {}
-}
diff --git a/javatests/dagger/functional/TypeWithInheritedMembersInjection.java b/javatests/dagger/functional/TypeWithInheritedMembersInjection.java
deleted file mode 100644
index b74f348..0000000
--- a/javatests/dagger/functional/TypeWithInheritedMembersInjection.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import javax.inject.Inject;
-
-final class TypeWithInheritedMembersInjection extends AbstractMiddleClassWithoutMembers {
-  @Inject TypeWithInheritedMembersInjection() {}
-}
-
diff --git a/javatests/dagger/functional/UnwrappedAnnotationKey.java b/javatests/dagger/functional/UnwrappedAnnotationKey.java
deleted file mode 100644
index e9298f2..0000000
--- a/javatests/dagger/functional/UnwrappedAnnotationKey.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-import dagger.multibindings.StringKey;
-
-@MapKey(unwrapValue = true)
-@interface UnwrappedAnnotationKey {
-  StringKey value();
-}
diff --git a/javatests/dagger/functional/WrappedAnnotationKey.java b/javatests/dagger/functional/WrappedAnnotationKey.java
deleted file mode 100644
index 0256111..0000000
--- a/javatests/dagger/functional/WrappedAnnotationKey.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional;
-
-import dagger.MapKey;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.StringKey;
-
-@MapKey(unwrapValue = false)
-@interface WrappedAnnotationKey {
-  StringKey value();
-  int[] integers();
-  ClassKey[] annotations();
-  Class<? extends Number>[] classes();
-}
diff --git a/javatests/dagger/functional/aot/DependsOnMissingArrayKey.java b/javatests/dagger/functional/aot/DependsOnMissingArrayKey.java
deleted file mode 100644
index 20a89d4..0000000
--- a/javatests/dagger/functional/aot/DependsOnMissingArrayKey.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-/**
- * Regression test for an ahead-of-time subcomponents bug where generating the name for a missing
- * binding method for a key of an array type threw an exception.
- */
-final class DependsOnMissingArrayKey {
-  @Module
-  abstract static class ModuleArrayDependencies {
-    @Provides
-    static int dependsOnMissingArrayType(int[] primitive, Object[] object, String[][] doubleArray) {
-      return 0;
-    }
-  }
-
-  @Subcomponent(modules = ModuleArrayDependencies.class)
-  interface HasMissingArrayBindings {
-    int dependsOnMissingArrayType();
-  }
-}
diff --git a/javatests/dagger/functional/aot/MapFrameworkInstanceWithContributionsInMultipleImplementationsTest.java b/javatests/dagger/functional/aot/MapFrameworkInstanceWithContributionsInMultipleImplementationsTest.java
deleted file mode 100644
index ae6b3a4..0000000
--- a/javatests/dagger/functional/aot/MapFrameworkInstanceWithContributionsInMultipleImplementationsTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.aot;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.StringKey;
-import java.util.Map;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests that framework instances of map bindings are properly instantiated in ahead-of-time mode
- * when contributions are made in 3 or more implementations.
- */
-@RunWith(JUnit4.class)
-public final class MapFrameworkInstanceWithContributionsInMultipleImplementationsTest {
-  @Subcomponent(modules = LeafModule.class)
-  interface Leaf {
-    Provider<Map<String, String>> providerOfMapOfValues();
-    Provider<Map<String, Provider<String>>> providerOfMapOfProviders();
-  }
-
-  @Module
-  interface LeafModule {
-    @Provides
-    @IntoMap
-    @StringKey("a")
-    static String fromLeaf() {
-      return "a";
-    }
-  }
-
-  @Subcomponent(modules = AncestorModule.class)
-  interface Ancestor {
-    Leaf leaf();
-  }
-
-  @Module
-  interface AncestorModule {
-    @Provides
-    @IntoMap
-    @StringKey("b")
-    static String fromAncestor() {
-      return "b";
-    }
-  }
-
-  @Component(modules = RootModule.class)
-  interface Root {
-    Ancestor ancestor();
-  }
-
-  @Module
-  interface RootModule {
-    @Provides
-    @IntoMap
-    @StringKey("c")
-    static String fromRoot() {
-      return "c";
-    }
-  }
-
-  @Test
-  public void mapFactoryCanBeInstantiatedAcrossComponentImplementations() {
-    Leaf leaf =
-        DaggerMapFrameworkInstanceWithContributionsInMultipleImplementationsTest_Root.create()
-            .ancestor()
-            .leaf();
-    assertThat(leaf.providerOfMapOfValues().get()).hasSize(3);
-    assertThat(leaf.providerOfMapOfProviders().get()).hasSize(3);
-  }
-}
diff --git a/javatests/dagger/functional/aot/MissingBindingReplacedWithGeneratedInstance.java b/javatests/dagger/functional/aot/MissingBindingReplacedWithGeneratedInstance.java
deleted file mode 100644
index 1813ad2..0000000
--- a/javatests/dagger/functional/aot/MissingBindingReplacedWithGeneratedInstance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Subcomponent;
-import javax.inject.Inject;
-
-/**
- * This class demonstrates a regression where a missing binding method was generated in a leaf
- * component and then satisfied in an ancestor with a generated instance binding. If the ancestor's
- * generated instance method had the same name as the formerly-missing binding method, Dagger would
- * generate code without a proper {@code DaggerOuter.this} reference:
- *
- * <pre>{@code
- * public class DaggerAncestor implements Ancestor {
- *   protected abstract Ancestor getAncestor();
- *
- *   protected abstract class LeafImpl extends DaggerLeaf {
- *     {@literal @Override}
- *     protected final Ancestor getAncestor() {
- *       return getAncestor();
- *       //     ^ should be DaggerAncestor.this.getAncestor()
- *     }
- *   }
- * }
- * }</pre>
- */
-final class MissingBindingReplacedWithGeneratedInstance {
-  @Subcomponent
-  interface Leaf {
-    DependsOnGeneratedInstance dependsOnGeneratedInstance();
-  }
-
-  static class DependsOnGeneratedInstance {
-    @Inject DependsOnGeneratedInstance(Ancestor generatedInstance) {}
-  }
-
-  @Subcomponent
-  interface Ancestor {
-    Leaf child();
-  }
-}
diff --git a/javatests/dagger/functional/aot/ModifiedFrameworkInstancesTest.java b/javatests/dagger/functional/aot/ModifiedFrameworkInstancesTest.java
deleted file mode 100644
index 7084f83..0000000
--- a/javatests/dagger/functional/aot/ModifiedFrameworkInstancesTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoSet;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ModifiedFrameworkInstancesTest {
-  static class DependsOnModifiableBinding {
-    @Inject
-    DependsOnModifiableBinding(Set<Integer> modifiableDependency) {}
-  }
-
-  @Module
-  interface ChildModule {
-    @Provides
-    @IntoSet
-    static int contribution() {
-      return 1;
-    }
-  }
-
-  @Subcomponent(modules = ChildModule.class)
-  interface Child {
-    Provider<DependsOnModifiableBinding> frameworkInstanceWithModifiedDependency();
-  }
-
-  @Module
-  interface ParentModule {
-    @Provides
-    @IntoSet
-    static int contribution() {
-      return 2;
-    }
-  }
-
-  @Component(modules = ParentModule.class)
-  interface Parent {
-    Child child();
-  }
-
-  @Test
-  public void dependsOnModifiedFrameworkInstance() {
-    DaggerModifiedFrameworkInstancesTest_Parent.create()
-        .child()
-        .frameworkInstanceWithModifiedDependency()
-        // Ensure that modified framework instances that are dependencies to other framework 
-        // instances from superclass implementations are initialized correctly. This fixes a
-        // regression where a null instance would be passed to the superclass initialization, and
-        // then a NullPointerException would be thrown when the factory attempted to satisfy the
-        // dependency in get(). If get() succeeds, this test should pass.
-        .get();
-  }
-}
diff --git a/javatests/dagger/functional/aot/PrunedBindingDependedOnInSuperInitializationTest.java b/javatests/dagger/functional/aot/PrunedBindingDependedOnInSuperInitializationTest.java
deleted file mode 100644
index 853e22b..0000000
--- a/javatests/dagger/functional/aot/PrunedBindingDependedOnInSuperInitializationTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class PrunedBindingDependedOnInSuperInitializationTest {
-  interface PrunedDependency {}
-
-  static class WillHavePrunedDependency {
-    @Inject WillHavePrunedDependency(PrunedDependency pruned) {}
-  }
-
-  @Subcomponent
-  interface Child {
-    Provider<WillHavePrunedDependency> frameworkInstance();
-  }
-
-  @Module
-  static class ParentModule {
-    @Provides
-    static WillHavePrunedDependency pruneDependency() {
-      return new WillHavePrunedDependency(new PrunedDependency() {});
-    }
-  }
-
-  @Component(modules = ParentModule.class)
-  interface Parent {
-    Child child();
-  }
-
-  @Test
-  public void prunedFrameworkInstanceBindingUsedInInitializationDoesntThrow() {
-    Parent parent = DaggerPrunedBindingDependedOnInSuperInitializationTest_Parent.create();
-    // This test ensures that pruned bindings that are used during unpruned initialization
-    // statements do not throw exceptions. If the subcomponent initialization succeeds, the test
-    // should pass
-    parent.child();
-  }
-}
diff --git a/javatests/dagger/functional/aot/PrunedFrameworkInstanceWithModuleInstanceTest.java b/javatests/dagger/functional/aot/PrunedFrameworkInstanceWithModuleInstanceTest.java
deleted file mode 100644
index f995789..0000000
--- a/javatests/dagger/functional/aot/PrunedFrameworkInstanceWithModuleInstanceTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.aot;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class PrunedFrameworkInstanceWithModuleInstanceTest {
-  static class Pruned {}
-
-  static class InjectsPruned {
-    @Inject
-    InjectsPruned(Provider<Pruned> pruned) {}
-  }
-
-  @Module
-  static class InstanceStateModule {
-    @Provides
-    /* intentionally not static */ Pruned pruned() {
-      return new Pruned();
-    }
-  }
-
-  @Subcomponent(modules = InstanceStateModule.class)
-  interface LeafWithoutCreator {
-    InjectsPruned injectsPruned();
-  }
-
-  @Subcomponent(modules = InstanceStateModule.class)
-  interface LeafWithCreator {
-    InjectsPruned injectsPruned();
-
-    @Subcomponent.Builder
-    interface Builder {
-      Builder module(InstanceStateModule module);
-      LeafWithCreator build();
-    }
-  }
-
-  @Module
-  interface RootModule {
-    @Provides
-    static InjectsPruned pruneBindingWithInstanceState() {
-      return new InjectsPruned(null);
-    }
-  }
-
-  @Component(modules = RootModule.class)
-  interface Root {
-    LeafWithoutCreator leafWithoutCreator(InstanceStateModule pruned);
-    LeafWithCreator.Builder leafWithCreator();
-  }
-
-  @Test
-  public void prunedBindingWithModuleInstance_doesntThrowDuringInitialization() {
-    Root root = DaggerPrunedFrameworkInstanceWithModuleInstanceTest_Root.create();
-
-    Object unused = root.leafWithoutCreator(new InstanceStateModule()).injectsPruned();
-    unused = root.leafWithCreator().module(new InstanceStateModule()).build().injectsPruned();
-  }
-}
diff --git a/javatests/dagger/functional/aot/ScopedBindsWithMissingDependency.java b/javatests/dagger/functional/aot/ScopedBindsWithMissingDependency.java
deleted file mode 100644
index 2723ac0..0000000
--- a/javatests/dagger/functional/aot/ScopedBindsWithMissingDependency.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Reusable;
-import dagger.Subcomponent;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import javax.inject.Scope;
-
-/**
- * A regression test for ahead-of-time subcomponents mode where a scoped {@link Binds} method whose
- * dependency was missing in a partial subcomponent implementation threw an exception in the
- * processor.
- */
-final class ScopedBindsWithMissingDependency {
-
-  @Retention(RetentionPolicy.RUNTIME)
-  @Scope
-  @interface CustomScope {}
-
-  @Module
-  interface ScopedBindsWithMissingDependencyModule {
-    @Binds
-    @CustomScope
-    Object bindsCustomScopeToMissingDep(String missingDependency);
-
-    @Binds
-    @Reusable
-    CharSequence bindsReusableScopeToMissingDep(String missingDependency);
-  }
-
-  @CustomScope
-  @Subcomponent(modules = ScopedBindsWithMissingDependencyModule.class)
-  interface HasScopedBindsWithMissingDependency {
-    Object customScopedBindsWithMissingDependency();
-    CharSequence reusableScopedBindsWithMissingDependency();
-  }
-}
diff --git a/javatests/dagger/functional/aot/SubcomponentWithInaccessibleMissingBindingMethod.java b/javatests/dagger/functional/aot/SubcomponentWithInaccessibleMissingBindingMethod.java
deleted file mode 100644
index 689689c..0000000
--- a/javatests/dagger/functional/aot/SubcomponentWithInaccessibleMissingBindingMethod.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Subcomponent;
-import dagger.functional.aot.sub.PublicTypeWithPackagePrivateMissingDep;
-import javax.inject.Provider;
-
-@Subcomponent
-interface SubcomponentWithInaccessibleMissingBindingMethod {
-  PublicTypeWithPackagePrivateMissingDep instance();
-  Provider<PublicTypeWithPackagePrivateMissingDep> frameworkInstance();
-}
diff --git a/javatests/dagger/functional/aot/SubcomponentWithModifiedInaccessibleDependency.java b/javatests/dagger/functional/aot/SubcomponentWithModifiedInaccessibleDependency.java
deleted file mode 100644
index 06cebb9..0000000
--- a/javatests/dagger/functional/aot/SubcomponentWithModifiedInaccessibleDependency.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot;
-
-import dagger.Subcomponent;
-import dagger.functional.aot.sub.BindsPackagePrivateModule;
-import dagger.functional.aot.sub.SubcomponentWithInaccessibleOptionalBindingMethod;
-
-/**
- * See {@link dagger.functional.aot.sub.SubcomponentWithInaccessibleOptionalBindingMethod}. This
- * subcomponent will induce a modified binding method for its single child for the key {@code
- * Optional<dagger.functional.aot.sub.PackagePrivate>}. When it tries to reimplement it, it must use
- * the publicly accessible type.
- */
-@Subcomponent(modules = BindsPackagePrivateModule.class)
-interface SubcomponentWithModifiedInaccessibleDependency {
-  SubcomponentWithInaccessibleOptionalBindingMethod child();
-}
diff --git a/javatests/dagger/functional/aot/sub/BindsPackagePrivateModule.java b/javatests/dagger/functional/aot/sub/BindsPackagePrivateModule.java
deleted file mode 100644
index 2eee3c9..0000000
--- a/javatests/dagger/functional/aot/sub/BindsPackagePrivateModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot.sub;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public final class BindsPackagePrivateModule {
-  @Provides
-  static PackagePrivate packagePrivate() {
-    return new PackagePrivate();
-  }
-}
diff --git a/javatests/dagger/functional/aot/sub/PackagePrivate.java b/javatests/dagger/functional/aot/sub/PackagePrivate.java
deleted file mode 100644
index c629f6e..0000000
--- a/javatests/dagger/functional/aot/sub/PackagePrivate.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot.sub;
-
-final class PackagePrivate {}
diff --git a/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateMissingDep.java b/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateMissingDep.java
deleted file mode 100644
index b5ced6f..0000000
--- a/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateMissingDep.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot.sub;
-
-import javax.inject.Inject;
-
-public class PublicTypeWithPackagePrivateMissingDep {
-  @Inject
-  PublicTypeWithPackagePrivateMissingDep(PackagePrivate packagePrivate) {}
-}
diff --git a/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateOptionalDep.java b/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateOptionalDep.java
deleted file mode 100644
index 1d69723..0000000
--- a/javatests/dagger/functional/aot/sub/PublicTypeWithPackagePrivateOptionalDep.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot.sub;
-
-import java.util.Optional;
-import javax.inject.Inject;
-
-public class PublicTypeWithPackagePrivateOptionalDep {
-  @Inject
-  PublicTypeWithPackagePrivateOptionalDep(Optional<PackagePrivate> packagePrivateOptional) {}
-}
diff --git a/javatests/dagger/functional/aot/sub/SubcomponentWithInaccessibleOptionalBindingMethod.java b/javatests/dagger/functional/aot/sub/SubcomponentWithInaccessibleOptionalBindingMethod.java
deleted file mode 100644
index d908b1c..0000000
--- a/javatests/dagger/functional/aot/sub/SubcomponentWithInaccessibleOptionalBindingMethod.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.aot.sub;
-
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.functional.aot.sub.SubcomponentWithInaccessibleOptionalBindingMethod.ExposesModifiablePackagePrivateBindingModule;
-import javax.inject.Provider;
-
-/**
- * This component will generate a modifiable binding method for the key {@code
- * Optional<PackagePrivate>} as a dependency of {@link PublicTypeWithPackagePrivateOptionalDep}.
- * Even though this subcomponent implementation can refer to the parameterized type, a subclass
- * implementation in another package will not be able to, and thus the return type must be reduced
- * to the publicly accessible type. This is exhibited in {@link
- * dagger.functional.aot.SubcomponentWithModifiedInaccessibleDependency}.
- */
-@Subcomponent(modules = ExposesModifiablePackagePrivateBindingModule.class)
-public interface SubcomponentWithInaccessibleOptionalBindingMethod {
-  PublicTypeWithPackagePrivateOptionalDep instance();
-  Provider<PublicTypeWithPackagePrivateOptionalDep> frameworkInstance();
-
-  @Module
-  interface ExposesModifiablePackagePrivateBindingModule {
-    @BindsOptionalOf
-    PackagePrivate optional();
-  }
-}
diff --git a/javatests/dagger/functional/binds/AccessesExposedComponent.java b/javatests/dagger/functional/binds/AccessesExposedComponent.java
deleted file mode 100644
index 61952b6..0000000
--- a/javatests/dagger/functional/binds/AccessesExposedComponent.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds;
-
-import dagger.Component;
-import dagger.functional.binds.subpackage.Exposed;
-import dagger.functional.binds.subpackage.ExposedModule;
-import dagger.functional.binds.subpackage.UsesExposedInjectsMembers;
-import java.util.List;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-/**
- * This component tests cases where the right-hand-side of a {@link dagger.Binds} method is not
- * accessible from the component, but the left-hand-side is. If the right-hand-side is represented
- * as a Provider (e.g. because it is scoped), then the raw {@code Provider.get()} will return {@link
- * Object}, which must be downcasted to the type accessible from the component. See {@code
- * instanceRequiresCast()} in {@link dagger.internal.codegen.DelegateBindingExpression}.
- */
-@Singleton
-@Component(modules = ExposedModule.class)
-interface AccessesExposedComponent {
-  Exposed exposed();
-  Provider<Exposed> exposedProvider();
-
-  List<? extends Exposed> listOfExposed();
-  Provider<List<? extends Exposed>> providerOfListOfExposed();
-
-  UsesExposedInjectsMembers usesExposedInjectsMembers();
-
-  /**
-   * This provider needs a {@code Provider<ExposedInjectsMembers>}, which is bound to a {@code
-   * Provider<NotExposedInjectsMembers>}. This method is here to make sure that the cast happens
-   * appropriately.
-   */
-  Provider<UsesExposedInjectsMembers> usesExposedInjectsMembersProvider();
-}
diff --git a/javatests/dagger/functional/binds/BindsCollectionsWithoutMultibindingsTest.java b/javatests/dagger/functional/binds/BindsCollectionsWithoutMultibindingsTest.java
deleted file mode 100644
index 90b1bbc..0000000
--- a/javatests/dagger/functional/binds/BindsCollectionsWithoutMultibindingsTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class BindsCollectionsWithoutMultibindingsTest {
-  @Module
-  abstract static class M {
-    @Provides
-    static HashSet<String> provideHashSet() {
-      HashSet<String> set = new HashSet<>();
-      set.add("binds");
-      set.add("set");
-      return set;
-    }
-
-    @Binds
-    abstract Set<String> bindStringSet(HashSet<String> set);
-
-    @Provides
-    static HashMap<String, String> provideHashMap() {
-      HashMap<String, String> map = new HashMap<>();
-      map.put("binds", "map");
-      map.put("without", "multibindings");
-      return map;
-    }
-
-    @Binds
-    abstract Map<String, String> bindStringMap(HashMap<String, String> map);
-  }
-
-  @Component(modules = M.class)
-  interface C {
-    Set<String> set();
-
-    Map<String, String> map();
-  }
-
-  @Test
-  public void works() {
-    C component = DaggerBindsCollectionsWithoutMultibindingsTest_C.create();
-
-    assertThat(component.set()).containsExactly("binds", "set");
-    assertThat(component.map())
-        .containsExactly(
-            "binds", "map",
-            "without", "multibindings");
-  }
-}
diff --git a/javatests/dagger/functional/binds/BindsTest.java b/javatests/dagger/functional/binds/BindsTest.java
deleted file mode 100644
index 999c303..0000000
--- a/javatests/dagger/functional/binds/BindsTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class BindsTest {
-
-  private TestComponent component;
-
-  @Before
-  public void setUp() {
-    component = DaggerTestComponent.create();
-  }
-
-  @Test
-  public void bindDelegates() {
-    assertThat(component.object()).isInstanceOf(FooOfStrings.class);
-    assertThat(component.fooOfStrings()).isInstanceOf(FooOfStrings.class);
-    assertThat(component.fooOfObjects()).isInstanceOf(FooOfObjects.class);
-    assertThat(component.fooOfIntegers()).isNotNull();
-  }
-
-  @Test
-  public void bindWithScope() {
-    assertThat(component.qualifiedFooOfStrings())
-        .isSameInstanceAs(component.qualifiedFooOfStrings());
-  }
-
-  @Test
-  public void multibindings() {
-    assertThat(component.foosOfNumbers()).hasSize(2);
-    assertThat(component.objects()).hasSize(3);
-    assertThat(component.charSequences()).hasSize(5);
-
-    assertThat(component.integerObjectMap())
-        .containsExactly(123, "123-string", 456, "456-string", 789, "789-string");
-    assertThat(component.integerProviderOfObjectMap()).hasSize(3);
-    assertThat(component.integerProviderOfObjectMap().get(123).get()).isEqualTo("123-string");
-    assertThat(component.integerProviderOfObjectMap().get(456).get()).isEqualTo("456-string");
-    assertThat(component.integerProviderOfObjectMap().get(789).get()).isEqualTo("789-string");
-
-    assertThat(component.qualifiedIntegerObjectMap()).hasSize(1);
-
-    assertThat(component.primitiveSet()).containsExactly(100);
-    assertThat(component.primitiveValueMap()).containsExactly(10, 100);
-  }
-}
diff --git a/javatests/dagger/functional/binds/Foo.java b/javatests/dagger/functional/binds/Foo.java
deleted file mode 100644
index 12b0e4e..0000000
--- a/javatests/dagger/functional/binds/Foo.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-/**
- * This is the type that will be bound.  We throw in generics just to complicate the test.
- */
-interface Foo<T> {}
diff --git a/javatests/dagger/functional/binds/FooOfObjects.java b/javatests/dagger/functional/binds/FooOfObjects.java
deleted file mode 100644
index c50f2fa..0000000
--- a/javatests/dagger/functional/binds/FooOfObjects.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import javax.inject.Inject;
-
-final class FooOfObjects implements Foo<Object> {
-  @Inject FooOfObjects() {}
-}
diff --git a/javatests/dagger/functional/binds/FooOfStrings.java b/javatests/dagger/functional/binds/FooOfStrings.java
deleted file mode 100644
index 42fc704..0000000
--- a/javatests/dagger/functional/binds/FooOfStrings.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import javax.inject.Inject;
-
-final class FooOfStrings implements Foo<String> {
-  @Inject
-  FooOfStrings() {}
-}
diff --git a/javatests/dagger/functional/binds/InterfaceModule.java b/javatests/dagger/functional/binds/InterfaceModule.java
deleted file mode 100644
index e9d36c0..0000000
--- a/javatests/dagger/functional/binds/InterfaceModule.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import dagger.Binds;
-import dagger.Module;
-
-@Module
-interface InterfaceModule {
-  @Binds Foo<Object> bindFooOfObjects(FooOfObjects impl);
-}
diff --git a/javatests/dagger/functional/binds/SimpleBindingModule.java b/javatests/dagger/functional/binds/SimpleBindingModule.java
deleted file mode 100644
index e1d5227..0000000
--- a/javatests/dagger/functional/binds/SimpleBindingModule.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-import dagger.functional.SomeQualifier;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-@Module(includes = InterfaceModule.class)
-abstract class SimpleBindingModule {
-  @Binds
-  abstract Object bindObject(FooOfStrings impl);
-
-  @Binds
-  @Reusable
-  @SomeQualifier
-  abstract Object bindReusableObject(FooOfStrings impl);
-
-  @Binds
-  abstract Foo<String> bindFooOfStrings(FooOfStrings impl);
-
-  @Binds
-  abstract Foo<? extends Number> bindFooOfNumbers(Foo<Integer> fooOfIntegers);
-
-  @Binds
-  @Singleton
-  @SomeQualifier
-  abstract Foo<String> bindQualifiedFooOfStrings(FooOfStrings impl);
-
-  @Provides
-  static Foo<Integer> provideFooOfIntegers() {
-    return new Foo<Integer>() {};
-  }
-
-  @Provides
-  static Foo<Double> provideFooOfDoubles() {
-    return new Foo<Double>() {};
-  }
-
-  @Binds
-  @IntoSet
-  abstract Foo<? extends Number> bindFooOfIntegersIntoSet(Foo<Integer> fooOfIntegers);
-
-  @Binds
-  @IntoSet
-  abstract Foo<? extends Number> bindFooExtendsNumberIntoSet(Foo<Double> fooOfDoubles);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<Object> bindSetOfFooNumbersToObjects(Set<Foo<? extends Number>> setOfFooNumbers);
-
-  @Binds
-  @IntoSet
-  abstract Object bindFooOfStringsIntoSetOfObjects(FooOfStrings impl);
-
-  @Provides
-  static HashSet<String> provideStringHashSet() {
-    return new HashSet<>(Arrays.asList("hash-string1", "hash-string2"));
-  }
-
-  @Provides
-  static TreeSet<CharSequence> provideCharSequenceTreeSet() {
-    return new TreeSet<CharSequence>(Arrays.asList("tree-charSequence1", "tree-charSequence2"));
-  }
-
-  @Provides
-  static Collection<CharSequence> provideCharSequenceCollection() {
-    return Arrays.<CharSequence>asList("list-charSequence");
-  }
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindHashSetOfStrings(HashSet<String> set);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindTreeSetOfCharSequences(TreeSet<CharSequence> set);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindCollectionOfCharSequences(Collection<CharSequence> collection);
-
-  @Binds
-  @IntoMap
-  @IntKey(123)
-  abstract Object bind123ForMap(@Named("For-123") String string);
-
-  @Binds
-  @IntoMap
-  @IntKey(456)
-  abstract Object bind456ForMap(@Named("For-456") String string);
-
-  @Provides
-  @IntoMap
-  @IntKey(789)
-  static Object provide789ForMap() {
-    return "789-string";
-  }
-
-  @Binds
-  @SomeQualifier
-  abstract int primitiveToPrimitive(int intValue);
-
-  @Binds
-  @IntoSet
-  abstract int intValueIntoSet(int intValue);
-
-  @Binds
-  @IntoMap
-  @IntKey(10)
-  abstract int intValueIntoMap(int intValue);
-
-  @Provides
-  static int intValue() {
-    return 100;
-  }
-
-  @Binds
-  @IntoMap
-  @IntKey(123)
-  @SomeQualifier
-  abstract Object bindFooOfStringsIntoQualifiedMap(FooOfStrings fooOfStrings);
-  
-  @Provides
-  @Named("For-123")
-  static String provide123String() {
-    return "123-string";
-  }
-
-  @Provides
-  @Named("For-456")
-  static String provide456String() {
-    return "456-string";
-  }
-}
diff --git a/javatests/dagger/functional/binds/TestComponent.java b/javatests/dagger/functional/binds/TestComponent.java
deleted file mode 100644
index 3299dc8..0000000
--- a/javatests/dagger/functional/binds/TestComponent.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.binds;
-
-import dagger.Component;
-import dagger.functional.SomeQualifier;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-@Singleton
-@Component(modules = SimpleBindingModule.class)
-public interface TestComponent {
-  Object object();
-
-  @SomeQualifier
-  Object reusableObject();
-
-  Foo<String> fooOfStrings();
-
-  Foo<Object> fooOfObjects();
-
-  @SomeQualifier
-  Foo<String> qualifiedFooOfStrings();
-
-  Foo<Integer> fooOfIntegers();
-
-  Set<Foo<? extends Number>> foosOfNumbers();
-
-  Set<Object> objects();
-
-  Set<CharSequence> charSequences();
-
-  Map<Integer, Object> integerObjectMap();
-
-  Map<Integer, Provider<Object>> integerProviderOfObjectMap();
-
-  @SomeQualifier Map<Integer, Object> qualifiedIntegerObjectMap();
-
-  @SomeQualifier int uniquePrimitive();
-
-  Set<Integer> primitiveSet();
-
-  Map<Integer, Integer> primitiveValueMap();
-}
diff --git a/javatests/dagger/functional/binds/subpackage/Exposed.java b/javatests/dagger/functional/binds/subpackage/Exposed.java
deleted file mode 100644
index 885aee4..0000000
--- a/javatests/dagger/functional/binds/subpackage/Exposed.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-public interface Exposed {}
\ No newline at end of file
diff --git a/javatests/dagger/functional/binds/subpackage/ExposedInjectsMembers.java b/javatests/dagger/functional/binds/subpackage/ExposedInjectsMembers.java
deleted file mode 100644
index 074289c..0000000
--- a/javatests/dagger/functional/binds/subpackage/ExposedInjectsMembers.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-public interface ExposedInjectsMembers {}
diff --git a/javatests/dagger/functional/binds/subpackage/ExposedModule.java b/javatests/dagger/functional/binds/subpackage/ExposedModule.java
deleted file mode 100644
index a2660d9..0000000
--- a/javatests/dagger/functional/binds/subpackage/ExposedModule.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import java.util.ArrayList;
-import java.util.List;
-import javax.inject.Singleton;
-
-@Module
-public abstract class ExposedModule {
-  @Binds
-  abstract Exposed notExposed(NotExposed notExposed);
-
-  @Provides
-  @Singleton // force a rawtypes Provider
-  static List<NotExposed> notExposedList() {
-    return new ArrayList<>();
-  }
-
-  @Binds
-  abstract List<? extends Exposed> bindList(List<NotExposed> notExposedList);
-
-  @Binds
-  abstract ExposedInjectsMembers bindExposedInjectsMembers(
-      NotExposedInjectsMembers notExposedInjectsMembers);
-}
diff --git a/javatests/dagger/functional/binds/subpackage/NotExposed.java b/javatests/dagger/functional/binds/subpackage/NotExposed.java
deleted file mode 100644
index a8774ee..0000000
--- a/javatests/dagger/functional/binds/subpackage/NotExposed.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton // force a Provider, which will not have a type parameter since this is not public
-class NotExposed implements Exposed {
-  @Inject
-  NotExposed() {}
-}
\ No newline at end of file
diff --git a/javatests/dagger/functional/binds/subpackage/NotExposedInjectsMembers.java b/javatests/dagger/functional/binds/subpackage/NotExposedInjectsMembers.java
deleted file mode 100644
index 1f6a1b7..0000000
--- a/javatests/dagger/functional/binds/subpackage/NotExposedInjectsMembers.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-import javax.inject.Inject;
-
-final class NotExposedInjectsMembers implements ExposedInjectsMembers {
-  @Inject Exposed exposed;
-
-  @Inject NotExposedInjectsMembers() {}
-}
diff --git a/javatests/dagger/functional/binds/subpackage/UsesExposedInjectsMembers.java b/javatests/dagger/functional/binds/subpackage/UsesExposedInjectsMembers.java
deleted file mode 100644
index 3ee2e8f..0000000
--- a/javatests/dagger/functional/binds/subpackage/UsesExposedInjectsMembers.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.binds.subpackage;
-
-import javax.inject.Inject;
-
-public class UsesExposedInjectsMembers {
-  @Inject ExposedInjectsMembers exposedInjectsMembers;
-
-  @Inject UsesExposedInjectsMembers(ExposedInjectsMembers exposedInjectsMembers) {}
-}
diff --git a/javatests/dagger/functional/builder/BuildMethodCovariantReturn.java b/javatests/dagger/functional/builder/BuildMethodCovariantReturn.java
deleted file mode 100644
index b55981f..0000000
--- a/javatests/dagger/functional/builder/BuildMethodCovariantReturn.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.builder;
-
-import dagger.Component;
-
-@Component
-interface BuildMethodCovariantReturn {
-
-  @Component.Builder
-  interface Builder {
-    Object build();
-  }
-}
diff --git a/javatests/dagger/functional/builder/BuildMethodCovariantReturnInherited.java b/javatests/dagger/functional/builder/BuildMethodCovariantReturnInherited.java
deleted file mode 100644
index 07ebbc8..0000000
--- a/javatests/dagger/functional/builder/BuildMethodCovariantReturnInherited.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.builder;
-
-import dagger.Component;
-
-interface BuildMethodCovariantReturnInherited {
-  @Component
-  interface Simple {
-    interface BuilderSupertype {
-      Object build();
-    }
-
-    @Component.Builder
-    interface Builder extends BuilderSupertype {}
-  }
-
-  interface ComponentSupertype {}
-
-  @Component
-  interface GenericBuilderType extends ComponentSupertype {
-    interface GenericBuilderSupertype<T> {
-      T build();
-    }
-
-    @Component.Builder
-    interface Builder extends GenericBuilderSupertype<ComponentSupertype> {}
-  }
-
-  interface ParameterizedComponentSupertype<T> {}
-
-  @Component
-  interface GenericComponentSupertypeAndBuilderSupertype
-      extends ParameterizedComponentSupertype<Object> {
-
-    interface GenericBuilderSupertype<T> {
-      ParameterizedComponentSupertype<T> build();
-    }
-
-    @Component.Builder
-    interface Builder extends GenericBuilderSupertype<Object> {}
-  }
-}
diff --git a/javatests/dagger/functional/builder/BuilderBindsInstanceParameterTest.java b/javatests/dagger/functional/builder/BuilderBindsInstanceParameterTest.java
deleted file mode 100644
index 33d3816..0000000
--- a/javatests/dagger/functional/builder/BuilderBindsInstanceParameterTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.builder;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests that {@code @BindsInstance} works when applied to the parameter of a builder's setter
- * method.
- */
-@RunWith(JUnit4.class)
-public final class BuilderBindsInstanceParameterTest {
-
-  @Component
-  interface TestComponent {
-    String s();
-
-    int i();
-
-    @Component.Builder
-    interface Builder {
-      // https://github.com/google/dagger/issues/1464
-      Builder s(@BindsInstance String notTheSameNameAsMethod);
-
-      Builder i(@BindsInstance int i);
-
-      TestComponent build();
-    }
-  }
-
-  @Test
-  public void builder_bindsInstanceOnParameter_allowed() {
-    TestComponent component = DaggerBuilderBindsInstanceParameterTest_TestComponent.builder()
-        .s("hello")
-        .i(42)
-        .build();
-    assertThat(component.s()).isEqualTo("hello");
-    assertThat(component.i()).isEqualTo(42);
-  }
-}
diff --git a/javatests/dagger/functional/builder/BuilderTest.java b/javatests/dagger/functional/builder/BuilderTest.java
deleted file mode 100644
index 75b15c4..0000000
--- a/javatests/dagger/functional/builder/BuilderTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class BuilderTest {
-
-  @Test public void interfaceBuilder() {
-    TestComponentWithBuilderInterface.Builder builder =
-        DaggerTestComponentWithBuilderInterface.builder();
-
-    // Make sure things fail if we don't set our required modules.
-    try {
-      builder.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder.intModule(new IntModuleIncludingDoubleAndFloat(1))
-        .stringModule(new StringModule("sam"))
-        .depComponent(new DepComponent() {});
-    builder.doubleModule(new DoubleModule());
-    // Don't set other modules -- make sure it works.
-    
-    TestComponentWithBuilderInterface component = builder.build();
-    assertThat(component.s()).isEqualTo("sam");
-    assertThat(component.i()).isEqualTo(1);
-    assertThat(component.d()).isEqualTo(4.2d);
-    assertThat(component.f()).isEqualTo(5.5f);
-    assertThat(component.l()).isEqualTo(6L);
-  }
-
-  @Test public void abstractClassBuilder() {
-    TestComponentWithBuilderAbstractClass.Builder builder =
-        TestComponentWithBuilderAbstractClass.builder();
-
-    // Make sure things fail if we don't set our required modules.
-    try {
-      builder.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder.intModule(new IntModuleIncludingDoubleAndFloat(1))
-        .stringModule(new StringModule("sam"))
-        .depComponent(new DepComponent() {});
-    builder.doubleModule(new DoubleModule());
-    // Don't set other modules -- make sure it works.
-    
-    TestComponentWithBuilderAbstractClass component = builder.build();
-    assertThat(component.s()).isEqualTo("sam");
-    assertThat(component.i()).isEqualTo(1);
-    assertThat(component.d()).isEqualTo(4.2d);
-    assertThat(component.f()).isEqualTo(5.5f);
-    assertThat(component.l()).isEqualTo(6L);
-  }
-
-  @Test public void interfaceGenericBuilder() {
-    TestComponentWithGenericBuilderInterface.Builder builder =
-        DaggerTestComponentWithGenericBuilderInterface.builder();
-
-    // Make sure things fail if we don't set our required modules.
-    try {
-      builder.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder.setM2(new IntModuleIncludingDoubleAndFloat(1))
-        .setM1(new StringModule("sam"))
-        .depComponent(new DepComponent() {});
-    builder.doubleModule(new DoubleModule());
-    // Don't set other modules -- make sure it works.
-    
-    TestComponentWithGenericBuilderInterface component = builder.build();
-    assertThat(component.s()).isEqualTo("sam");
-    assertThat(component.i()).isEqualTo(1);
-    assertThat(component.d()).isEqualTo(4.2d);
-    assertThat(component.f()).isEqualTo(5.5f);
-    assertThat(component.l()).isEqualTo(6L);
-  }
-
-  @Test public void abstractClassGenericBuilder() {
-    TestComponentWithGenericBuilderAbstractClass.Builder builder =
-        DaggerTestComponentWithGenericBuilderAbstractClass.builder();
-
-    // Make sure things fail if we don't set our required modules.
-    try {
-      builder.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder.setM2(new IntModuleIncludingDoubleAndFloat(1))
-        .setM1(new StringModule("sam"))
-        .depComponent(new DepComponent() {});
-    builder.doubleModule(new DoubleModule());
-    // Don't set other modules -- make sure it works.
-    
-    TestComponentWithGenericBuilderAbstractClass component = builder.build();
-    assertThat(component.s()).isEqualTo("sam");
-    assertThat(component.i()).isEqualTo(1);
-    assertThat(component.d()).isEqualTo(4.2d);
-    assertThat(component.f()).isEqualTo(5.5f);
-    assertThat(component.l()).isEqualTo(6L);
-  }
-  
-  @Test public void subcomponents_interface() {
-    ParentComponent parent = DaggerParentComponent.create();    
-    TestChildComponentWithBuilderInterface.Builder builder1 = parent.childInterfaceBuilder();
-    try {
-      builder1.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder1.setM2(new IntModuleIncludingDoubleAndFloat(1))
-        .setM1(new StringModule("sam"))
-        .set(new ByteModule((byte)7));
-    builder1.set(new FloatModule());
-    TestChildComponentWithBuilderInterface child1 = builder1.build();
-    assertThat(child1.s()).isEqualTo("sam");
-    assertThat(child1.i()).isEqualTo(1);
-    assertThat(child1.d()).isEqualTo(4.2d);
-    assertThat(child1.f()).isEqualTo(5.5f);
-    assertThat(child1.l()).isEqualTo(6L);
-    assertThat(child1.b()).isEqualTo((byte)7);
-  }
-  
-  @Test public void subcomponents_abstractclass() {
-    ParentComponent parent = DaggerParentComponent.create();
-    TestChildComponentWithBuilderAbstractClass.Builder builder2 =
-        parent.childAbstractClassBuilder();
-    try {
-      builder2.build();
-      fail();
-    } catch(IllegalStateException expected) {}
-    
-    builder2.setM2(new IntModuleIncludingDoubleAndFloat(10))
-        .setM1(new StringModule("tara"))
-        .set(new ByteModule((byte)70));
-    builder2.set(new FloatModule());
-    TestChildComponentWithBuilderAbstractClass child2 = builder2.build();
-    assertThat(child2.s()).isEqualTo("tara");
-    assertThat(child2.i()).isEqualTo(10);
-    assertThat(child2.d()).isEqualTo(4.2d);
-    assertThat(child2.f()).isEqualTo(5.5f);
-    assertThat(child2.l()).isEqualTo(6L);
-    assertThat(child2.b()).isEqualTo((byte)70);
-  }
-    
-  @Test
-  public void grandchildren() {
-    ParentComponent parent = DaggerParentComponent.create();
-    MiddleChild middle1 = parent.middleBuilder().set(new StringModule("sam")).build();
-    Grandchild grandchild1 =
-        middle1.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(21)).build();
-    Grandchild grandchild2 =
-        middle1.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(22)).build();
-    
-    assertThat(middle1.s()).isEqualTo("sam");
-    assertThat(grandchild1.i()).isEqualTo(21);
-    assertThat(grandchild1.s()).isEqualTo("sam");
-    assertThat(grandchild2.i()).isEqualTo(22);
-    assertThat(grandchild2.s()).isEqualTo("sam");
-
-    // Make sure grandchildren from newer children have no relation to the older ones.
-    MiddleChild middle2 = parent.middleBuilder().set(new StringModule("tara")).build();
-    Grandchild grandchild3 =
-        middle2.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(23)).build();
-    Grandchild grandchild4 =
-        middle2.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(24)).build();
-    
-    assertThat(middle2.s()).isEqualTo("tara");
-    assertThat(grandchild3.i()).isEqualTo(23);
-    assertThat(grandchild3.s()).isEqualTo("tara");
-    assertThat(grandchild4.i()).isEqualTo(24);
-    assertThat(grandchild4.s()).isEqualTo("tara");
-  }
-  
-  @Test
-  public void diamondGrandchildren() {
-    ParentComponent parent = DaggerParentComponent.create();
-    MiddleChild middle = parent.middleBuilder().set(new StringModule("sam")).build();
-    OtherMiddleChild other = parent.otherBuilder().set(new StringModule("tara")).build();
-    
-    Grandchild middlegrand =
-        middle.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(21)).build();
-    Grandchild othergrand =
-        other.grandchildBuilder().set(new IntModuleIncludingDoubleAndFloat(22)).build();
-    
-    assertThat(middle.s()).isEqualTo("sam");
-    assertThat(other.s()).isEqualTo("tara");
-    assertThat(middlegrand.s()).isEqualTo("sam");
-    assertThat(othergrand.s()).isEqualTo("tara");
-    assertThat(middlegrand.i()).isEqualTo(21);
-    assertThat(othergrand.i()).isEqualTo(22);
-  }
-  
-  @Test
-  public void genericSubcomponentMethod() {
-    ParentOfGenericComponent parent =
-        DaggerParentOfGenericComponent.builder().stringModule(new StringModule("sam")).build();
-    Grandchild.Builder builder = parent.subcomponentBuilder();
-    Grandchild child = builder.set(new IntModuleIncludingDoubleAndFloat(21)).build();
-    assertThat(child.s()).isEqualTo("sam");
-    assertThat(child.i()).isEqualTo(21);
-  }
-  
-  @Test
-  public void requireSubcomponentBuilderProviders() {
-    ParentComponent parent = DaggerParentComponent.create();
-    MiddleChild middle =
-        parent
-            .requiresMiddleChildBuilder()
-            .subcomponentBuilderProvider()
-            .get()
-            .set(new StringModule("sam"))
-            .build();
-    Grandchild grandchild =
-        middle
-            .requiresGrandchildBuilder()
-            .subcomponentBuilderProvider()
-            .get()
-            .set(new IntModuleIncludingDoubleAndFloat(12))
-            .build();
-    assertThat(middle.s()).isEqualTo("sam");
-    assertThat(grandchild.i()).isEqualTo(12);
-    assertThat(grandchild.s()).isEqualTo("sam");
-  }
-  
-  @Test
-  public void requireSubcomponentBuilders() {
-    ParentComponent parent = DaggerParentComponent.create();
-    MiddleChild middle =
-        parent
-            .requiresMiddleChildBuilder()
-            .subcomponentBuilder()
-            .set(new StringModule("sam"))
-            .build();
-    Grandchild grandchild =
-        middle
-            .requiresGrandchildBuilder()
-            .subcomponentBuilder()
-            .set(new IntModuleIncludingDoubleAndFloat(12))
-            .build();
-    assertThat(middle.s()).isEqualTo("sam");
-    assertThat(grandchild.i()).isEqualTo(12);
-    assertThat(grandchild.s()).isEqualTo("sam");
-  }
-}
diff --git a/javatests/dagger/functional/builder/ByteModule.java b/javatests/dagger/functional/builder/ByteModule.java
deleted file mode 100644
index 4b6602f..0000000
--- a/javatests/dagger/functional/builder/ByteModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class ByteModule {
-  final byte b;
-
-  ByteModule(byte b) {
-    this.b = b;
-  }
-  
-  @Provides byte b() { return b; }
-}
diff --git a/javatests/dagger/functional/builder/DepComponent.java b/javatests/dagger/functional/builder/DepComponent.java
deleted file mode 100644
index 6e85c7a..0000000
--- a/javatests/dagger/functional/builder/DepComponent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-
-@Component
-interface DepComponent {
-}
diff --git a/javatests/dagger/functional/builder/DoubleModule.java b/javatests/dagger/functional/builder/DoubleModule.java
deleted file mode 100644
index d1be37c..0000000
--- a/javatests/dagger/functional/builder/DoubleModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class DoubleModule {
-  @Provides
-  double d() {
-    return 4.2d;
-  }
-}
diff --git a/javatests/dagger/functional/builder/FloatModule.java b/javatests/dagger/functional/builder/FloatModule.java
deleted file mode 100644
index d9990c0..0000000
--- a/javatests/dagger/functional/builder/FloatModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class FloatModule {  
-  @Provides
-  float f() {
-    return 5.5f;
-  }
-}
diff --git a/javatests/dagger/functional/builder/GenericParent.java b/javatests/dagger/functional/builder/GenericParent.java
deleted file mode 100644
index 9563103..0000000
--- a/javatests/dagger/functional/builder/GenericParent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-interface GenericParent<B> {  
-  B subcomponentBuilder();
-}
diff --git a/javatests/dagger/functional/builder/Grandchild.java b/javatests/dagger/functional/builder/Grandchild.java
deleted file mode 100644
index 45fe213..0000000
--- a/javatests/dagger/functional/builder/Grandchild.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = IntModuleIncludingDoubleAndFloat.class)
-interface Grandchild {
-  int i();
-  String s();
-
-  @Subcomponent.Builder
-  interface Builder {
-    Grandchild build();
-    Builder set(IntModuleIncludingDoubleAndFloat intModule);
-  }
-}
diff --git a/javatests/dagger/functional/builder/IntModuleIncludingDoubleAndFloat.java b/javatests/dagger/functional/builder/IntModuleIncludingDoubleAndFloat.java
deleted file mode 100644
index 37f5ad7..0000000
--- a/javatests/dagger/functional/builder/IntModuleIncludingDoubleAndFloat.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module(includes = { DoubleModule.class, FloatModule.class })
-class IntModuleIncludingDoubleAndFloat {
-  final int integer;
-
-  IntModuleIncludingDoubleAndFloat(int integer) {
-    this.integer = integer;
-  }
-  
-  @Provides
-  int integer() {
-    return integer;
-  }
-}
diff --git a/javatests/dagger/functional/builder/LongModule.java b/javatests/dagger/functional/builder/LongModule.java
deleted file mode 100644
index 7b777ec..0000000
--- a/javatests/dagger/functional/builder/LongModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class LongModule {  
-  @Provides
-  long l() {
-    return 6L;
-  }
-}
diff --git a/javatests/dagger/functional/builder/MiddleChild.java b/javatests/dagger/functional/builder/MiddleChild.java
deleted file mode 100644
index 762e2a0..0000000
--- a/javatests/dagger/functional/builder/MiddleChild.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Subcomponent;
-
-@MiddleScope
-@Subcomponent(modules = StringModule.class)
-interface MiddleChild {
-  String s();
-  
-  Grandchild.Builder grandchildBuilder();
-  
-  RequiresSubcomponentBuilder<Grandchild.Builder> requiresGrandchildBuilder();
-  
-  @Subcomponent.Builder
-  interface Builder {
-    MiddleChild build();
-    Builder set(StringModule stringModule);
-  }
-}
diff --git a/javatests/dagger/functional/builder/MiddleScope.java b/javatests/dagger/functional/builder/MiddleScope.java
deleted file mode 100644
index ac63626..0000000
--- a/javatests/dagger/functional/builder/MiddleScope.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-@Scope
-@Retention(RUNTIME)
-@interface MiddleScope {
-
-}
diff --git a/javatests/dagger/functional/builder/OtherMiddleChild.java b/javatests/dagger/functional/builder/OtherMiddleChild.java
deleted file mode 100644
index 7ecc014..0000000
--- a/javatests/dagger/functional/builder/OtherMiddleChild.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Subcomponent;
-
-@MiddleScope
-@Subcomponent(modules = {StringModule.class, LongModule.class})
-interface OtherMiddleChild {
-  long l();
-  String s();
-  
-  Grandchild.Builder grandchildBuilder();
-  
-  @Subcomponent.Builder
-  interface Builder {
-    OtherMiddleChild build();
-    Builder set(StringModule stringModule);
-  }
-}
diff --git a/javatests/dagger/functional/builder/ParentComponent.java b/javatests/dagger/functional/builder/ParentComponent.java
deleted file mode 100644
index 425ba9a..0000000
--- a/javatests/dagger/functional/builder/ParentComponent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-import javax.inject.Singleton;
-
-@Singleton
-@Component
-interface ParentComponent {  
-  TestChildComponentWithBuilderAbstractClass.Builder childAbstractClassBuilder();
-  TestChildComponentWithBuilderInterface.Builder childInterfaceBuilder();
-  
-  MiddleChild.Builder middleBuilder();
-  OtherMiddleChild.Builder otherBuilder();
-  
-  RequiresSubcomponentBuilder<MiddleChild.Builder> requiresMiddleChildBuilder();
-}
diff --git a/javatests/dagger/functional/builder/ParentOfGenericComponent.java b/javatests/dagger/functional/builder/ParentOfGenericComponent.java
deleted file mode 100644
index daeb7d9..0000000
--- a/javatests/dagger/functional/builder/ParentOfGenericComponent.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-import javax.inject.Singleton;
-
-@Component(modules = StringModule.class)
-@Singleton
-interface ParentOfGenericComponent extends GenericParent<Grandchild.Builder> {}
diff --git a/javatests/dagger/functional/builder/PrivateConstructors.java b/javatests/dagger/functional/builder/PrivateConstructors.java
deleted file mode 100644
index e5e9aa6..0000000
--- a/javatests/dagger/functional/builder/PrivateConstructors.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.builder;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-
-final class PrivateConstructors {
-  @Module
-  static final class M {
-    @Provides
-    static String provideString() {
-      return "str";
-    }
-
-    private M() {}
-  }
-
-  @Component(modules = M.class)
-  interface C {
-    String string();
-
-    @Component.Builder
-    interface Builder {
-      // M should not be required, even though the constructor is inaccessible
-      C build();
-    }
-  }
-}
diff --git a/javatests/dagger/functional/builder/RequiresSubcomponentBuilder.java b/javatests/dagger/functional/builder/RequiresSubcomponentBuilder.java
deleted file mode 100644
index a8dfa21..0000000
--- a/javatests/dagger/functional/builder/RequiresSubcomponentBuilder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-class RequiresSubcomponentBuilder<B> {
-  private final Provider<B> subcomponentBuilderProvider;
-  private final B subcomponentBuilder;
-
-  @Inject
-  RequiresSubcomponentBuilder(Provider<B> subcomponentBuilderProvider, B subcomponentBuilder) {
-    this.subcomponentBuilderProvider = subcomponentBuilderProvider;
-    this.subcomponentBuilder = subcomponentBuilder;
-  }
-
-  Provider<B> subcomponentBuilderProvider() {
-    return subcomponentBuilderProvider;
-  }
-  
-  B subcomponentBuilder() {
-    return subcomponentBuilder;
-  }
-}
diff --git a/javatests/dagger/functional/builder/StringModule.java b/javatests/dagger/functional/builder/StringModule.java
deleted file mode 100644
index 9fbaa5b..0000000
--- a/javatests/dagger/functional/builder/StringModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class StringModule {
-  final String string;
-
-  StringModule(String string) {
-    this.string = string;
-  }
-  
-  @Provides
-  String string() {
-    return string;
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestChildComponentWithBuilderAbstractClass.java b/javatests/dagger/functional/builder/TestChildComponentWithBuilderAbstractClass.java
deleted file mode 100644
index 1527a44..0000000
--- a/javatests/dagger/functional/builder/TestChildComponentWithBuilderAbstractClass.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class,
-    LongModule.class, ByteModule.class})
-interface TestChildComponentWithBuilderAbstractClass {
-  String s();
-  int i();
-  long l();
-  float f();
-  double d();
-  byte b();
- 
-  abstract class SharedBuilder<B, C, M1, M2> {
-    abstract C build(); // Test resolving return type of build()
-    abstract B setM1(M1 m1); // Test resolving return type & param of setter
-    abstract SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
-    abstract void setM3(DoubleModule doubleModule);  // Test being overridden
-    abstract SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test returning supertype.
-  }
-  
-  @Subcomponent.Builder
-  abstract class Builder extends SharedBuilder<Builder, TestChildComponentWithBuilderAbstractClass,
-      StringModule, IntModuleIncludingDoubleAndFloat> {
-    @Override abstract Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariance
-    @Override abstract void setM3(DoubleModule doubleModule); // Test simple overrides allowed    
-    abstract void set(ByteModule byteModule);
-    
-    // Note we're missing LongModule -- it's implicit
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestChildComponentWithBuilderInterface.java b/javatests/dagger/functional/builder/TestChildComponentWithBuilderInterface.java
deleted file mode 100644
index a02b1a1..0000000
--- a/javatests/dagger/functional/builder/TestChildComponentWithBuilderInterface.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class,
-    LongModule.class, ByteModule.class})
-interface TestChildComponentWithBuilderInterface {
-  String s();
-  int i();
-  long l();
-  float f();
-  double d();
-  byte b();
-  
-  interface SharedBuilder<B, C, M1, M2> {
-    C build(); // Test resolving return type of build()
-    B setM1(M1 m1); // Test resolving return type & param of setter
-    SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
-    void setM3(DoubleModule doubleModule);  // Test being overridden
-    SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test return type is supertype.
-  }
-  
-  @Subcomponent.Builder
-  interface Builder extends SharedBuilder<Builder, TestChildComponentWithBuilderInterface,
-      StringModule, IntModuleIncludingDoubleAndFloat> {
-    @Override Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides
-    @Override void setM3(DoubleModule doubleModule); // Test simple overrides allowed    
-    void set(ByteModule byteModule);
-    
-    // Note we're missing LongModule -- it's implicit
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestComponentWithBuilderAbstractClass.java b/javatests/dagger/functional/builder/TestComponentWithBuilderAbstractClass.java
deleted file mode 100644
index 636c8f4..0000000
--- a/javatests/dagger/functional/builder/TestComponentWithBuilderAbstractClass.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-
-@Component(
-    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
-    dependencies = DepComponent.class)
-abstract class TestComponentWithBuilderAbstractClass {
-  
-  static Builder builder() {
-    return DaggerTestComponentWithBuilderAbstractClass.builder();
-  }
-  
-  abstract String s();
-  abstract int i();
-  abstract long l();
-  abstract float f();
-  abstract double d();
-  
-
-  static abstract class SharedBuilder {
-    // Make sure we use the overriding signature.
-    abstract Object build();
-    
-    Object stringModule(@SuppressWarnings("unused") StringModule stringModule) {
-      return null;
-    } 
-
-    SharedBuilder ignoredLongModule(@SuppressWarnings("unused") LongModule longModule) {
-      return null;
-    }
-    
-  }
-  
-  @Component.Builder
-  static abstract class Builder extends SharedBuilder {
-    @Override abstract TestComponentWithBuilderAbstractClass build(); // Narrowing return type
-    @Override abstract Builder stringModule(StringModule stringModule); // Make abstract & narrow
-    abstract Builder intModule(IntModuleIncludingDoubleAndFloat intModule);
-    abstract void doubleModule(DoubleModule doubleModule); // Module w/o args
-    abstract void depComponent(DepComponent depComponent);
-
-    Builder ignoredIntModule(
-        @SuppressWarnings("unused") IntModuleIncludingDoubleAndFloat intModule) {
-      return null;
-    }    
-    
-    // Note we're missing LongModule & FloatModule -- they/re implicit
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestComponentWithBuilderInterface.java b/javatests/dagger/functional/builder/TestComponentWithBuilderInterface.java
deleted file mode 100644
index ba55090..0000000
--- a/javatests/dagger/functional/builder/TestComponentWithBuilderInterface.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-
-@Component(
-    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
-    dependencies = DepComponent.class)
-interface TestComponentWithBuilderInterface {
-  String s();
-  int i();
-  long l();
-  float f();
-  double d();
-  
-  interface SharedBuilder {
-    // Make sure we use the overriding signature.
-    Object build();
-    Object stringModule(StringModule m1); 
-  }
-  
-  @Component.Builder
-  interface Builder extends SharedBuilder {
-    @Override TestComponentWithBuilderInterface build(); // Narrowing return type
-    @Override Builder stringModule(StringModule stringModule); // Narrowing return type
-    Builder intModule(IntModuleIncludingDoubleAndFloat intModule);
-    void doubleModule(DoubleModule doubleModule); // Module w/o args
-    void depComponent(DepComponent depComponent);
-    
-    // Note we're missing LongModule & FloatModule -- they/re implicit
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestComponentWithGenericBuilderAbstractClass.java b/javatests/dagger/functional/builder/TestComponentWithGenericBuilderAbstractClass.java
deleted file mode 100644
index 5324957..0000000
--- a/javatests/dagger/functional/builder/TestComponentWithGenericBuilderAbstractClass.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-
-@Component(
-    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
-    dependencies = DepComponent.class)
-interface TestComponentWithGenericBuilderAbstractClass {
-  String s();
-  int i();
-  long l();
-  float f();
-  double d();
-  
-  static abstract class SharedBuilder<B, C, M1, M2> {
-    abstract C build(); // Test resolving return type of build()
-    abstract B setM1(M1 m1); // Test resolving return type & param of setter
-    abstract SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
-    abstract void doubleModule(DoubleModule doubleModule);  // Test being overridden
-    abstract SharedBuilder<B, C, M1, M2> depComponent(FloatModule floatModule); // Test return type
-  }
-  
-  @Component.Builder
-  static abstract class Builder extends SharedBuilder<Builder,
-      TestComponentWithGenericBuilderAbstractClass, StringModule,
-      IntModuleIncludingDoubleAndFloat> {
-    @Override abstract Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides
-    @Override abstract void doubleModule(DoubleModule module3); // Test simple overrides allowed    
-    abstract void depComponent(DepComponent depComponent);
-    
-    // Note we're missing LongModule & FloatModule -- they're implicit
-  }
-}
diff --git a/javatests/dagger/functional/builder/TestComponentWithGenericBuilderInterface.java b/javatests/dagger/functional/builder/TestComponentWithGenericBuilderInterface.java
deleted file mode 100644
index 8e30c78..0000000
--- a/javatests/dagger/functional/builder/TestComponentWithGenericBuilderInterface.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.builder;
-
-import dagger.Component;
-
-@Component(
-    modules = {StringModule.class, IntModuleIncludingDoubleAndFloat.class, LongModule.class},
-    dependencies = DepComponent.class)
-interface TestComponentWithGenericBuilderInterface {
-  String s();
-  int i();
-  long l();
-  float f();
-  double d();
-  
-  interface SharedBuilder<B, C, M1, M2> {
-    C build(); // Test resolving return type of build()
-    B setM1(M1 m1); // Test resolving return type & param of setter
-    SharedBuilder<B, C, M1, M2> setM2(M2 m2); // Test being overridden
-    void doubleModule(DoubleModule doubleModule);  // Test being overridden
-    SharedBuilder<B, C, M1, M2> set(FloatModule floatModule); // Test return type is supertype.
-  }
-  
-  @Component.Builder
-  interface Builder extends SharedBuilder<Builder, TestComponentWithGenericBuilderInterface,
-      StringModule, IntModuleIncludingDoubleAndFloat> {
-    @Override Builder setM2(IntModuleIncludingDoubleAndFloat m2); // Test covariant overrides allowed
-    @Override void doubleModule(DoubleModule module3); // Test simple overrides allowed    
-    void depComponent(DepComponent depComponent);
-    
-    // Note we're missing M5 -- that's implicit.
-  }
-}
diff --git a/javatests/dagger/functional/builderbinds/BuilderBindsTest.java b/javatests/dagger/functional/builderbinds/BuilderBindsTest.java
deleted file mode 100644
index b5e5225..0000000
--- a/javatests/dagger/functional/builderbinds/BuilderBindsTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.builderbinds;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableList;
-import dagger.functional.builderbinds.TestComponent.Builder;
-import java.util.Arrays;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class BuilderBindsTest {
-
-  @Test
-  public void builderBinds() {
-    TestComponent.Builder builder =
-        DaggerTestComponent.builder()
-            .count(5)
-            .l(10L)
-            .input("foo")
-            .nullableInput("bar")
-            .listOfString(Arrays.asList("x", "y", "z"));
-    builder.boundInSubtype(20);
-    TestComponent component = builder.build();
-    assertThat(component.count()).isEqualTo(5);
-    assertThat(component.input()).isEqualTo("foo");
-    assertThat(component.nullableInput()).isEqualTo("bar");
-    assertThat(component.listOfString()).containsExactly("x", "y", "z").inOrder();
-  }
-
-  @Test
-  public void builderBindsNullableWithNull() {
-    Builder builder =
-        DaggerTestComponent.builder()
-            .count(5)
-            .l(10L)
-            .input("foo")
-            .nullableInput(null)
-            .listOfString(ImmutableList.of());
-    builder.boundInSubtype(20);
-    TestComponent component = builder.build();
-
-    assertThat(component.count()).isEqualTo(5);
-    assertThat(component.input()).isEqualTo("foo");
-    assertThat(component.nullableInput()).isNull();
-    assertThat(component.listOfString()).isEmpty();
-  }
-
-  @Test
-  public void builderBindsNonNullableWithNull() {
-    try {
-      DaggerTestComponent.builder().count(5).l(10L).input(null);
-      fail("expected NullPointerException");
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test
-  public void builderBindsPrimitiveNotSet() {
-    try {
-      TestComponent.Builder builder =
-          DaggerTestComponent.builder()
-              .l(10L)
-              .input("foo")
-              .nullableInput("bar")
-              .listOfString(ImmutableList.of());
-      builder.boundInSubtype(20);
-      builder.build();
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-    }
-  }
-
-  @Test
-  public void builderBindsNonNullableNotSet() {
-    try {
-      TestComponent.Builder builder =
-          DaggerTestComponent.builder()
-              .count(5)
-              .l(10L)
-              .nullableInput("foo")
-              .listOfString(ImmutableList.of());
-      builder.boundInSubtype(20);
-      builder.build();
-      fail("expected IllegalStateException");
-    } catch (IllegalStateException expected) {
-    }
-  }
-
-  @Test
-  public void builderBindsNullableNotSet() {
-    Builder builder =
-        DaggerTestComponent.builder().count(5).l(10L).input("foo").listOfString(ImmutableList.of());
-    builder.boundInSubtype(20);
-    TestComponent component = builder.build();
-    assertThat(component.count()).isEqualTo(5);
-    assertThat(component.input()).isEqualTo("foo");
-    assertThat(component.nullableInput()).isNull();
-    assertThat(component.listOfString()).isEmpty();
-  }
-}
diff --git a/javatests/dagger/functional/builderbinds/BuilderSupertype.java b/javatests/dagger/functional/builderbinds/BuilderSupertype.java
deleted file mode 100644
index 5828f9d..0000000
--- a/javatests/dagger/functional/builderbinds/BuilderSupertype.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.builderbinds;
-
-import dagger.BindsInstance;
-import javax.inject.Named;
-
-interface BuilderSupertype {
-  @BindsInstance
-  void boundInSubtype(@Named("subtype") int subtype);
-}
diff --git a/javatests/dagger/functional/builderbinds/Nullable.java b/javatests/dagger/functional/builderbinds/Nullable.java
deleted file mode 100644
index 7924484..0000000
--- a/javatests/dagger/functional/builderbinds/Nullable.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.builderbinds;
-
-@interface Nullable {}
diff --git a/javatests/dagger/functional/builderbinds/TestComponent.java b/javatests/dagger/functional/builderbinds/TestComponent.java
deleted file mode 100644
index 23a32b1..0000000
--- a/javatests/dagger/functional/builderbinds/TestComponent.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.builderbinds;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import java.util.List;
-import javax.inject.Named;
-
-@Component
-interface TestComponent {
-  int count();
-
-  long l();
-
-  @Named("input")
-  String input();
-
-  @Nullable
-  @Named("nullable input")
-  String nullableInput();
-
-  List<String> listOfString();
-
-  @Named("subtype")
-  int boundInSubtype();
-
-  @Component.Builder
-  interface Builder extends BuilderSupertype {
-    @BindsInstance
-    Builder count(int count);
-
-    @BindsInstance
-    Builder l(long l);
-
-    @BindsInstance
-    Builder input(@Named("input") String input);
-
-    @BindsInstance
-    Builder nullableInput(@Nullable @Named("nullable input") String nullableInput);
-
-    @BindsInstance
-    Builder listOfString(List<String> listOfString);
-
-    TestComponent build();
-  }
-}
diff --git a/javatests/dagger/functional/cycle/CycleTest.java b/javatests/dagger/functional/cycle/CycleTest.java
deleted file mode 100644
index d489bc6..0000000
--- a/javatests/dagger/functional/cycle/CycleTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.cycle;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.cycle.Cycles.A;
-import dagger.functional.cycle.Cycles.BindsCycleComponent;
-import dagger.functional.cycle.Cycles.C;
-import dagger.functional.cycle.Cycles.ChildCycleComponent;
-import dagger.functional.cycle.Cycles.CycleComponent;
-import dagger.functional.cycle.Cycles.CycleMapComponent;
-import dagger.functional.cycle.Cycles.S;
-import dagger.functional.cycle.Cycles.SelfCycleComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class CycleTest {
-  @Test
-  public void providerIndirectionSelfCycle() {
-    SelfCycleComponent selfCycleComponent = DaggerCycles_SelfCycleComponent.create();
-    S s = selfCycleComponent.s();
-    assertThat(s.sProvider.get()).isNotNull();
-  }
-
-  @Test
-  public void providerIndirectionCycle() {
-    CycleComponent cycleComponent = DaggerCycles_CycleComponent.create();
-    A a = cycleComponent.a();
-    C c = cycleComponent.c();
-    assertThat(c.aProvider.get()).isNotNull();
-    assertThat(a.b.c.aProvider.get()).isNotNull();
-    assertThat(a.e.d.b.c.aProvider.get()).isNotNull();
-  }
-
-  @Test
-  public void lazyIndirectionSelfCycle() {
-    SelfCycleComponent selfCycleComponent = DaggerCycles_SelfCycleComponent.create();
-    S s = selfCycleComponent.s();
-    assertThat(s.sLazy.get()).isNotNull();
-  }
-
-  @Test
-  public void lazyIndirectionCycle() {
-    CycleComponent cycleComponent = DaggerCycles_CycleComponent.create();
-    A a = cycleComponent.a();
-    C c = cycleComponent.c();
-    assertThat(c.aLazy.get()).isNotNull();
-    assertThat(a.b.c.aLazy.get()).isNotNull();
-    assertThat(a.e.d.b.c.aLazy.get()).isNotNull();
-  }
-  
-  @Test
-  public void subcomponentIndirectionCycle() {
-    ChildCycleComponent childCycleComponent = DaggerCycles_CycleComponent.create().child();
-    A a = childCycleComponent.a();
-    assertThat(a.b.c.aProvider.get()).isNotNull();
-    assertThat(a.e.d.b.c.aProvider.get()).isNotNull();
-  }
-  
-  @Test
-  public void providerMapIndirectionCycle() {
-    CycleMapComponent cycleMapComponent = DaggerCycles_CycleMapComponent.create();
-    assertThat(cycleMapComponent.y()).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfX).containsKey("X");
-    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X")).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X").get()).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfX.get("X").get().y).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfX).hasSize(1);
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY).containsKey("Y");
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y")).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get()).isNotNull();
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get().mapOfProvidersOfX).hasSize(1);
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY.get("Y").get().mapOfProvidersOfY).hasSize(1);
-    assertThat(cycleMapComponent.y().mapOfProvidersOfY).hasSize(1);
-  }
-
-  /**
-   * Tests that a cycle where a {@code @Binds} binding depends on a binding that has to be deferred
-   * works.
-   */
-  @Test
-  public void cycleWithDeferredBinds() {
-    BindsCycleComponent bindsCycleComponent = DaggerCycles_BindsCycleComponent.create();
-    assertThat(bindsCycleComponent.bar()).isNotNull();
-  }
-}
diff --git a/javatests/dagger/functional/cycle/Cycles.java b/javatests/dagger/functional/cycle/Cycles.java
deleted file mode 100644
index f4faeab..0000000
--- a/javatests/dagger/functional/cycle/Cycles.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.cycle;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Lazy;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.StringKey;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/**
- * Cycle classes used for testing cyclic dependencies.
- *
- * <pre>
- * {@literal A ← (E ← D ← B ← C ← Provider<A>, Lazy<A>), (B ← C ← Provider<A>, Lazy<A>)}
- * {@literal S ← Provider<S>, Lazy<S>}
- * </pre>
- */
-final class Cycles {
-  private Cycles() {}
-
-  static class A {
-    public final B b;
-    public final E e;
-
-    @Inject
-    A(E e, B b) {
-      this.e = e;
-      this.b = b;
-    }
-  }
-
-  static class B {
-    public final C c;
-
-    @Inject
-    B(C c) {
-      this.c = c;
-    }
-  }
-
-  static class C {
-    public final Provider<A> aProvider;
-    @Inject public Lazy<A> aLazy;
-    @Inject public Provider<Lazy<A>> aLazyProvider;
-
-    @Inject
-    C(Provider<A> aProvider) {
-      this.aProvider = aProvider;
-    }
-  }
-
-  static class D {
-    public final B b;
-
-    @Inject
-    D(B b) {
-      this.b = b;
-    }
-  }
-
-  static class E {
-    public final D d;
-
-    @Inject
-    E(D d) {
-      this.d = d;
-    }
-  }
-
-  static class S {
-    public final Provider<S> sProvider;
-    @Inject public Lazy<S> sLazy;
-
-    @Inject
-    S(Provider<S> sProvider) {
-      this.sProvider = sProvider;
-    }
-  }
-
-  static class X {
-    public final Y y;
-
-    @Inject
-    X(Y y) {
-      this.y = y;
-    }
-  }
-
-  static class Y {
-    public final Map<String, Provider<X>> mapOfProvidersOfX;
-    public final Map<String, Provider<Y>> mapOfProvidersOfY;
-
-    @Inject
-    Y(Map<String, Provider<X>> mapOfProvidersOfX, Map<String, Provider<Y>> mapOfProvidersOfY) {
-      this.mapOfProvidersOfX = mapOfProvidersOfX;
-      this.mapOfProvidersOfY = mapOfProvidersOfY;
-    }
-  }
-
-  @Module
-  abstract static class CycleMapModule {
-    @Binds
-    @IntoMap
-    @StringKey("X")
-    abstract X x(X x);
-
-    @Binds
-    @IntoMap
-    @StringKey("Y")
-    abstract Y y(Y y);
-  }
-
-  @SuppressWarnings("dependency-cycle")
-  @Component(modules = CycleMapModule.class)
-  interface CycleMapComponent {
-    Y y();
-  }
-
-  @SuppressWarnings("dependency-cycle")
-  @Component(modules = CycleModule.class)
-  interface CycleComponent {
-    A a();
-
-    C c();
-
-    ChildCycleComponent child();
-  }
-
-  @Module
-  static class CycleModule {
-    @Provides
-    static Object provideObjectWithCycle(@SuppressWarnings("unused") Provider<Object> object) {
-      return "object";
-    }
-  }
-
-  @SuppressWarnings("dependency-cycle")
-  @Component
-  interface SelfCycleComponent {
-    S s();
-  }
-
-  @Subcomponent
-  interface ChildCycleComponent {
-    @SuppressWarnings("dependency-cycle")
-    A a();
-
-    @SuppressWarnings("dependency-cycle")
-    Object object();
-  }
-
-  interface Foo {}
-
-  static class Bar implements Foo {
-    @Inject
-    Bar(Provider<Foo> fooProvider) {}
-  }
-
-  /**
-   * A component with a cycle in which a {@code @Binds} binding depends on the binding that has to
-   * be deferred.
-   */
-  @Component(modules = BindsCycleModule.class)
-  interface BindsCycleComponent {
-    Bar bar();
-  }
-
-  @Module
-  abstract static class BindsCycleModule {
-    @Binds
-    abstract Foo foo(Bar bar);
-  }
-}
diff --git a/javatests/dagger/functional/cycle/DoubleCheckCycleTest.java b/javatests/dagger/functional/cycle/DoubleCheckCycleTest.java
deleted file mode 100644
index b77ee3e..0000000
--- a/javatests/dagger/functional/cycle/DoubleCheckCycleTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.cycle;
-
-import static com.google.common.truth.Truth.assertThat;
-import static java.lang.Thread.State.BLOCKED;
-import static java.lang.Thread.State.WAITING;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static org.junit.Assert.fail;
-
-import com.google.common.util.concurrent.SettableFuture;
-import com.google.common.util.concurrent.Uninterruptibles;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DoubleCheckCycleTest {
-  // TODO(b/77916397): Migrate remaining tests in DoubleCheckTest to functional tests in this class.
-
-  /** A qualifier for a reentrant scoped binding. */
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface Reentrant {}
-
-  /** A module to be overridden in each test. */
-  @Module
-  static class OverrideModule {
-    @Provides
-    @Singleton
-    Object provideObject() {
-      throw new IllegalStateException("This method should be overridden in tests");
-    }
-
-    @Provides
-    @Singleton
-    @Reentrant
-    Object provideReentrantObject(@Reentrant Provider<Object> provider) {
-      throw new IllegalStateException("This method should be overridden in tests");
-    }
-  }
-
-  @Singleton
-  @Component(modules = OverrideModule.class)
-  interface TestComponent {
-    Object getObject();
-    @Reentrant Object getReentrantObject();
-  }
-
-  @Test
-  public void testNonReentrant() {
-    AtomicInteger callCount = new AtomicInteger(0);
-
-    // Provides a non-reentrant binding. The provides method should only be called once.
-    DoubleCheckCycleTest.TestComponent component =
-        DaggerDoubleCheckCycleTest_TestComponent.builder()
-            .overrideModule(
-                new OverrideModule() {
-                  @Override Object provideObject() {
-                    callCount.getAndIncrement();
-                    return new Object();
-                  }
-                })
-            .build();
-
-    assertThat(callCount.get()).isEqualTo(0);
-    Object first = component.getObject();
-    assertThat(callCount.get()).isEqualTo(1);
-    Object second = component.getObject();
-    assertThat(callCount.get()).isEqualTo(1);
-    assertThat(first).isSameInstanceAs(second);
-  }
-
-  @Test
-  public void testReentrant() {
-    AtomicInteger callCount = new AtomicInteger(0);
-
-    // Provides a reentrant binding. Even though it's scoped, the provides method is called twice.
-    // In this case, we allow it since the same instance is returned on the second call.
-    DoubleCheckCycleTest.TestComponent component =
-        DaggerDoubleCheckCycleTest_TestComponent.builder()
-            .overrideModule(
-                new OverrideModule() {
-                  @Override Object provideReentrantObject(Provider<Object> provider) {
-                    if (callCount.incrementAndGet() == 1) {
-                      return provider.get();
-                    }
-                    return new Object();
-                  }
-                })
-            .build();
-
-    assertThat(callCount.get()).isEqualTo(0);
-    Object first = component.getReentrantObject();
-    assertThat(callCount.get()).isEqualTo(2);
-    Object second = component.getReentrantObject();
-    assertThat(callCount.get()).isEqualTo(2);
-    assertThat(first).isSameInstanceAs(second);
-  }
-
-  @Test
-  public void testFailingReentrant() {
-    AtomicInteger callCount = new AtomicInteger(0);
-
-    // Provides a failing reentrant binding. Even though it's scoped, the provides method is called
-    // twice. In this case we throw an exception since a different instance is provided on the
-    // second call.
-    DoubleCheckCycleTest.TestComponent component =
-        DaggerDoubleCheckCycleTest_TestComponent.builder()
-            .overrideModule(
-                new OverrideModule() {
-                  @Override Object provideReentrantObject(Provider<Object> provider) {
-                    if (callCount.incrementAndGet() == 1) {
-                      provider.get();
-                      return new Object();
-                    }
-                    return new Object();
-                  }
-                })
-            .build();
-
-    assertThat(callCount.get()).isEqualTo(0);
-    try {
-      component.getReentrantObject();
-      fail("Expected IllegalStateException");
-    } catch (IllegalStateException e) {
-      assertThat(e).hasMessageThat().contains("Scoped provider was invoked recursively");
-    }
-    assertThat(callCount.get()).isEqualTo(2);
-  }
-
-  @Test(timeout = 5000)
-
-  public void testGetFromMultipleThreads() throws Exception {
-    AtomicInteger callCount = new AtomicInteger(0);
-    AtomicInteger requestCount = new AtomicInteger(0);
-    SettableFuture<Object> future = SettableFuture.create();
-
-    // Provides a non-reentrant binding. In this case, we return a SettableFuture so that we can
-    // control when the provides method returns.
-    DoubleCheckCycleTest.TestComponent component =
-        DaggerDoubleCheckCycleTest_TestComponent.builder()
-            .overrideModule(
-                new OverrideModule() {
-                  @Override
-                  Object provideObject() {
-                    callCount.incrementAndGet();
-                    try {
-                      return Uninterruptibles.getUninterruptibly(future);
-                    } catch (ExecutionException e) {
-                      throw new RuntimeException(e);
-                    }
-                  }
-                })
-            .build();
-
-    int numThreads = 10;
-    CountDownLatch remainingTasks = new CountDownLatch(numThreads);
-    List<Thread> tasks = new ArrayList<>(numThreads);
-    List<Object> values = Collections.synchronizedList(new ArrayList<>(numThreads));
-
-    // Set up multiple threads that call component.getObject().
-    for (int i = 0; i < numThreads; i++) {
-      tasks.add(
-          new Thread(
-              () -> {
-                requestCount.incrementAndGet();
-                values.add(component.getObject());
-                remainingTasks.countDown();
-              }));
-    }
-
-    // Check initial conditions
-    assertThat(remainingTasks.getCount()).isEqualTo(10);
-    assertThat(requestCount.get()).isEqualTo(0);
-    assertThat(callCount.get()).isEqualTo(0);
-    assertThat(values).isEmpty();
-
-    // Start all threads
-    tasks.forEach(Thread::start);
-
-    // Wait for all threads to wait/block.
-    long waiting = 0;
-    while (waiting != numThreads) {
-      waiting =
-          tasks.stream()
-              .map(Thread::getState)
-              .filter(state -> state == WAITING || state == BLOCKED)
-              .count();
-    }
-
-    // Check the intermediate state conditions.
-    // * All 10 threads should have requested the binding, but none should have finished.
-    // * Only 1 thread should have reached the provides method.
-    // * None of the threads should have set a value (since they are waiting for future to be set).
-    assertThat(remainingTasks.getCount()).isEqualTo(10);
-    assertThat(requestCount.get()).isEqualTo(10);
-    assertThat(callCount.get()).isEqualTo(1);
-    assertThat(values).isEmpty();
-
-    // Set the future and wait on all remaining threads to finish.
-    Object futureValue = new Object();
-    future.set(futureValue);
-    remainingTasks.await();
-
-    // Check the final state conditions.
-    // All values should be set now, and they should all be equal to the same instance.
-    assertThat(remainingTasks.getCount()).isEqualTo(0);
-    assertThat(requestCount.get()).isEqualTo(10);
-    assertThat(callCount.get()).isEqualTo(1);
-    assertThat(values).isEqualTo(Collections.nCopies(numThreads, futureValue));
-  }
-}
diff --git a/javatests/dagger/functional/cycle/LongCycle.java b/javatests/dagger/functional/cycle/LongCycle.java
deleted file mode 100644
index 1b3fb24..0000000
--- a/javatests/dagger/functional/cycle/LongCycle.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.cycle;
-
-import dagger.Component;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/**
- * Component with a long enough cycle such that the initialization of a provider happens in a
- * separate {@code initialize} method from the one where it is used as a delegated factory.
- *
- */
-// Each nested class's constructor has an intentionally unused parameter.
-@SuppressWarnings("unused")
-final class LongCycle {
-  static class Class1 { @Inject Class1(Class2 class2) {} }
-  static class Class2 { @Inject Class2(Class3 class3) {} }
-  static class Class3 { @Inject Class3(Class4 class4) {} }
-  static class Class4 { @Inject Class4(Class5 class5) {} }
-  static class Class5 { @Inject Class5(Class6 class6) {} }
-  static class Class6 { @Inject Class6(Class7 class7) {} }
-  static class Class7 { @Inject Class7(Class8 class8) {} }
-  static class Class8 { @Inject Class8(Class9 class9) {} }
-  static class Class9 { @Inject Class9(Class10 class10) {} }
-  static class Class10 { @Inject Class10(Class11 class11) {} }
-  static class Class11 { @Inject Class11(Class12 class12) {} }
-  static class Class12 { @Inject Class12(Class13 class13) {} }
-  static class Class13 { @Inject Class13(Class14 class14) {} }
-  static class Class14 { @Inject Class14(Class15 class15) {} }
-  static class Class15 { @Inject Class15(Class16 class16) {} }
-  static class Class16 { @Inject Class16(Class17 class17) {} }
-  static class Class17 { @Inject Class17(Class18 class18) {} }
-  static class Class18 { @Inject Class18(Class19 class19) {} }
-  static class Class19 { @Inject Class19(Class20 class20) {} }
-  static class Class20 { @Inject Class20(Class21 class21) {} }
-  static class Class21 { @Inject Class21(Class22 class22) {} }
-  static class Class22 { @Inject Class22(Class23 class23) {} }
-  static class Class23 { @Inject Class23(Class24 class24) {} }
-  static class Class24 { @Inject Class24(Class25 class25) {} }
-  static class Class25 { @Inject Class25(Class26 class26) {} }
-  static class Class26 { @Inject Class26(Class27 class27) {} }
-  static class Class27 { @Inject Class27(Class28 class28) {} }
-  static class Class28 { @Inject Class28(Class29 class29) {} }
-  static class Class29 { @Inject Class29(Class30 class30) {} }
-  static class Class30 { @Inject Class30(Class31 class31) {} }
-  static class Class31 { @Inject Class31(Class32 class32) {} }
-  static class Class32 { @Inject Class32(Class33 class33) {} }
-  static class Class33 { @Inject Class33(Class34 class34) {} }
-  static class Class34 { @Inject Class34(Class35 class35) {} }
-  static class Class35 { @Inject Class35(Class36 class36) {} }
-  static class Class36 { @Inject Class36(Class37 class37) {} }
-  static class Class37 { @Inject Class37(Class38 class38) {} }
-  static class Class38 { @Inject Class38(Class39 class39) {} }
-  static class Class39 { @Inject Class39(Class40 class40) {} }
-  static class Class40 { @Inject Class40(Class41 class41) {} }
-  static class Class41 { @Inject Class41(Class42 class42) {} }
-  static class Class42 { @Inject Class42(Class43 class43) {} }
-  static class Class43 { @Inject Class43(Class44 class44) {} }
-  static class Class44 { @Inject Class44(Class45 class45) {} }
-  static class Class45 { @Inject Class45(Class46 class46) {} }
-  static class Class46 { @Inject Class46(Class47 class47) {} }
-  static class Class47 { @Inject Class47(Class48 class48) {} }
-  static class Class48 { @Inject Class48(Class49 class49) {} }
-  static class Class49 { @Inject Class49(Class50 class50) {} }
-  static class Class50 { @Inject Class50(Class51 class51) {} }
-  static class Class51 { @Inject Class51(Class52 class52) {} }
-  static class Class52 { @Inject Class52(Class53 class53) {} }
-  static class Class53 { @Inject Class53(Class54 class54) {} }
-  static class Class54 { @Inject Class54(Class55 class55) {} }
-  static class Class55 { @Inject Class55(Class56 class56) {} }
-  static class Class56 { @Inject Class56(Class57 class57) {} }
-  static class Class57 { @Inject Class57(Class58 class58) {} }
-  static class Class58 { @Inject Class58(Class59 class59) {} }
-  static class Class59 { @Inject Class59(Class60 class60) {} }
-  static class Class60 { @Inject Class60(Class61 class61) {} }
-  static class Class61 { @Inject Class61(Class62 class62) {} }
-  static class Class62 { @Inject Class62(Class63 class63) {} }
-  static class Class63 { @Inject Class63(Class64 class64) {} }
-  static class Class64 { @Inject Class64(Class65 class65) {} }
-  static class Class65 { @Inject Class65(Class66 class66) {} }
-  static class Class66 { @Inject Class66(Class67 class67) {} }
-  static class Class67 { @Inject Class67(Class68 class68) {} }
-  static class Class68 { @Inject Class68(Class69 class69) {} }
-  static class Class69 { @Inject Class69(Class70 class70) {} }
-  static class Class70 { @Inject Class70(Class71 class71) {} }
-  static class Class71 { @Inject Class71(Class72 class72) {} }
-  static class Class72 { @Inject Class72(Class73 class73) {} }
-  static class Class73 { @Inject Class73(Class74 class74) {} }
-  static class Class74 { @Inject Class74(Class75 class75) {} }
-  static class Class75 { @Inject Class75(Class76 class76) {} }
-  static class Class76 { @Inject Class76(Class77 class77) {} }
-  static class Class77 { @Inject Class77(Class78 class78) {} }
-  static class Class78 { @Inject Class78(Class79 class79) {} }
-  static class Class79 { @Inject Class79(Class80 class80) {} }
-  static class Class80 { @Inject Class80(Class81 class81) {} }
-  static class Class81 { @Inject Class81(Class82 class82) {} }
-  static class Class82 { @Inject Class82(Class83 class83) {} }
-  static class Class83 { @Inject Class83(Class84 class84) {} }
-  static class Class84 { @Inject Class84(Class85 class85) {} }
-  static class Class85 { @Inject Class85(Class86 class86) {} }
-  static class Class86 { @Inject Class86(Class87 class87) {} }
-  static class Class87 { @Inject Class87(Class88 class88) {} }
-  static class Class88 { @Inject Class88(Class89 class89) {} }
-  static class Class89 { @Inject Class89(Class90 class90) {} }
-  static class Class90 { @Inject Class90(Class91 class91) {} }
-  static class Class91 { @Inject Class91(Class92 class92) {} }
-  static class Class92 { @Inject Class92(Class93 class93) {} }
-  static class Class93 { @Inject Class93(Class94 class94) {} }
-  static class Class94 { @Inject Class94(Class95 class95) {} }
-  static class Class95 { @Inject Class95(Class96 class96) {} }
-  static class Class96 { @Inject Class96(Class97 class97) {} }
-  static class Class97 { @Inject Class97(Class98 class98) {} }
-  static class Class98 { @Inject Class98(Class99 class99) {} }
-  static class Class99 { @Inject Class99(Class100 class100) {} }
-  static class Class100 { @Inject Class100(Class101 class101) {} }
-  static class Class101 { @Inject Class101(Provider<Class1> class1Provider) {} }
-
-  @SuppressWarnings("dependency-cycle")
-  @Component
-  interface LongCycleComponent {
-    Class1 class1();
-  }
-
-  private LongCycle() {}
-}
diff --git a/javatests/dagger/functional/cycle/LongCycleTest.java b/javatests/dagger/functional/cycle/LongCycleTest.java
deleted file mode 100644
index a6244b1..0000000
--- a/javatests/dagger/functional/cycle/LongCycleTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.cycle;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.TruthJUnit.assume;
-import static java.util.Arrays.stream;
-
-import dagger.functional.cycle.LongCycle.LongCycleComponent;
-import java.lang.reflect.Method;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class LongCycleTest {
-
-  /**
-   * Tests a cycle long enough that the real factory is created in a separate initialize method from
-   * the delegate factory.
-   */
-  @Test
-  public void longCycle() {
-    LongCycleComponent longCycleComponent = DaggerLongCycle_LongCycleComponent.create();
-    assertThat(longCycleComponent.class1()).isNotNull();
-  }
-
-  /**
-   * Fails if {@link LongCycleComponent} doesn't have a long enough cycle to make sure the real
-   * factory is created in a separate method from the delegate factory.
-   */
-  @Test
-  public void longCycleHasMoreThanOneInitializeMethod() {
-    assume().that(System.getProperty("dagger.mode")).doesNotContain("FastInit");
-    boolean hasInitialize2 =
-        stream(DaggerLongCycle_LongCycleComponent.class.getDeclaredMethods())
-            .map(Method::getName)
-            .anyMatch(name -> name.equals("initialize2"));
-    assertWithMessage("LongCycleComponent impl has an initialize2 method")
-        .that(hasInitialize2)
-        .isTrue();
-  }
-}
diff --git a/javatests/dagger/functional/factory/AbstractModule.java b/javatests/dagger/functional/factory/AbstractModule.java
deleted file mode 100644
index 83a13d6..0000000
--- a/javatests/dagger/functional/factory/AbstractModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-abstract class AbstractModule {
-  @Provides
-  static String provideString() {
-    return "foo";
-  }
-}
diff --git a/javatests/dagger/functional/factory/ConcreteModuleThatCouldBeAbstract.java b/javatests/dagger/functional/factory/ConcreteModuleThatCouldBeAbstract.java
deleted file mode 100644
index 32591a2..0000000
--- a/javatests/dagger/functional/factory/ConcreteModuleThatCouldBeAbstract.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class ConcreteModuleThatCouldBeAbstract {
-  @Provides
-  static double provideDouble() {
-    return 42.0;
-  }
-}
diff --git a/javatests/dagger/functional/factory/Dependency.java b/javatests/dagger/functional/factory/Dependency.java
deleted file mode 100644
index 90dc294..0000000
--- a/javatests/dagger/functional/factory/Dependency.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-final class Dependency {
-  Object object() {
-    return "bar";
-  }
-}
diff --git a/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java b/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java
deleted file mode 100644
index 83505e9..0000000
--- a/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static org.junit.Assert.fail;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for component factories with {@link BindsInstance} parameters. */
-@RunWith(JUnit4.class)
-public final class FactoryBindsInstanceTest {
-
-  @Component
-  interface BindsInstanceComponent {
-    String string();
-
-    @Component.Factory
-    interface Factory {
-      BindsInstanceComponent create(@BindsInstance String string);
-    }
-  }
-
-  @Test
-  public void bindsInstance() {
-    BindsInstanceComponent component =
-        DaggerFactoryBindsInstanceTest_BindsInstanceComponent.factory().create("baz");
-    assertThat(component.string()).isEqualTo("baz");
-  }
-
-  @Test
-  public void nonNullableBindsInstance_failsOnNull() {
-    try {
-      DaggerFactoryBindsInstanceTest_BindsInstanceComponent.factory().create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Target({METHOD, PARAMETER})
-  @Retention(RUNTIME)
-  @interface Nullable {}
-
-  @Component
-  interface NullableBindsInstanceComponent {
-    @Nullable
-    String string();
-
-    @Component.Factory
-    interface Factory {
-      NullableBindsInstanceComponent create(@BindsInstance @Nullable String string);
-    }
-  }
-
-  @Test
-  public void nullableBindsInstance_doesNotFailOnNull() {
-    NullableBindsInstanceComponent component =
-        DaggerFactoryBindsInstanceTest_NullableBindsInstanceComponent.factory().create(null);
-    assertThat(component.string()).isEqualTo(null);
-  }
-
-  @Component
-  interface PrimitiveBindsInstanceComponent {
-    int getInt();
-
-    @Component.Factory
-    interface Factory {
-      PrimitiveBindsInstanceComponent create(@BindsInstance int i);
-    }
-  }
-
-  @Test
-  public void primitiveBindsInstance() {
-    PrimitiveBindsInstanceComponent component =
-        DaggerFactoryBindsInstanceTest_PrimitiveBindsInstanceComponent.factory().create(1);
-    assertThat(component.getInt()).isEqualTo(1);
-  }
-}
diff --git a/javatests/dagger/functional/factory/FactoryDependenciesTest.java b/javatests/dagger/functional/factory/FactoryDependenciesTest.java
deleted file mode 100644
index 35a0b85..0000000
--- a/javatests/dagger/functional/factory/FactoryDependenciesTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import dagger.Component;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for factories for components with a dependency. */
-@RunWith(JUnit4.class)
-public final class FactoryDependenciesTest {
-
-  @Component(dependencies = Dependency.class)
-  interface DependencyComponent {
-    Object object();
-
-    @Component.Factory
-    interface Factory {
-      DependencyComponent create(Dependency dependency);
-    }
-  }
-
-  @Test
-  public void dependency() {
-    DependencyComponent component =
-        DaggerFactoryDependenciesTest_DependencyComponent.factory().create(new Dependency());
-    assertThat(component.object()).isEqualTo("bar");
-  }
-
-  @Test
-  public void dependency_failsOnNull() {
-    try {
-      DaggerFactoryDependenciesTest_DependencyComponent.factory().create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/functional/factory/FactoryImplicitModulesTest.java b/javatests/dagger/functional/factory/FactoryImplicitModulesTest.java
deleted file mode 100644
index 143f322..0000000
--- a/javatests/dagger/functional/factory/FactoryImplicitModulesTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import dagger.Component;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for factories for components with modules that do not require an instance to be passed to
- * the factory. Includes both tests where the module does not have a corresponding parameter in the
- * factory method and where it does have a parameter, for cases where that's allowed.
- */
-@RunWith(JUnit4.class)
-public final class FactoryImplicitModulesTest {
-
-  @Component(modules = AbstractModule.class)
-  interface AbstractModuleComponent {
-    String string();
-
-    @Component.Factory
-    interface Factory {
-      AbstractModuleComponent create();
-    }
-  }
-
-  @Test
-  public void abstractModule() {
-    AbstractModuleComponent component =
-        DaggerFactoryImplicitModulesTest_AbstractModuleComponent.factory().create();
-    assertThat(component.string()).isEqualTo("foo");
-  }
-
-  @Component(modules = InstantiableConcreteModule.class)
-  interface InstantiableConcreteModuleComponent {
-    int getInt();
-
-    @Component.Factory
-    interface Factory {
-      InstantiableConcreteModuleComponent create();
-    }
-  }
-
-  @Test
-  public void instantiableConcreteModule() {
-    InstantiableConcreteModuleComponent component =
-        DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleComponent.factory().create();
-    assertThat(component.getInt()).isEqualTo(42);
-  }
-
-  @Component(modules = InstantiableConcreteModule.class)
-  interface InstantiableConcreteModuleWithFactoryParameterComponent {
-    int getInt();
-
-    @Component.Factory
-    interface Factory {
-      InstantiableConcreteModuleWithFactoryParameterComponent create(
-          InstantiableConcreteModule module);
-    }
-  }
-
-  @Test
-  public void instantiableConcreteModule_withFactoryParameter() {
-    InstantiableConcreteModuleWithFactoryParameterComponent component =
-        DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleWithFactoryParameterComponent
-            .factory()
-            .create(new InstantiableConcreteModule());
-    assertThat(component.getInt()).isEqualTo(42);
-  }
-
-  @Test
-  public void instantiableConcreteModule_withFactoryParameter_failsOnNull() {
-    try {
-      DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleWithFactoryParameterComponent
-          .factory()
-          .create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Component(modules = ConcreteModuleThatCouldBeAbstract.class)
-  interface ConcreteModuleThatCouldBeAbstractComponent {
-    double getDouble();
-
-    @Component.Factory
-    interface Factory {
-      ConcreteModuleThatCouldBeAbstractComponent create();
-    }
-  }
-
-  @Test
-  public void concreteModuleThatCouldBeAbstract() {
-    ConcreteModuleThatCouldBeAbstractComponent component =
-        DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractComponent.factory()
-            .create();
-    assertThat(component.getDouble()).isEqualTo(42.0);
-  }
-
-  @Component(modules = ConcreteModuleThatCouldBeAbstract.class)
-  interface ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent {
-    double getDouble();
-
-    @Component.Factory
-    interface Factory {
-      ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent create(
-          ConcreteModuleThatCouldBeAbstract module);
-    }
-  }
-
-  @Test
-  public void concreteModuleThatCouldBeAbstract_withFactoryParameter() {
-    ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent component =
-        DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent
-            .factory()
-            .create(new ConcreteModuleThatCouldBeAbstract());
-    assertThat(component.getDouble()).isEqualTo(42.0);
-  }
-
-  @Test
-  public void concreteModuleThatCouldBeAbstract_withFactoryParameter_failsOnNull() {
-    // This matches what builders do when there's a setter for such a module; the setter checks that
-    // the argument is not null but otherwise ignores it.
-    // It's possible that we shouldn't even allow such a parameter for a factory, since unlike a
-    // builder, where the setter can just not be called, a factory doesn't give the option of not
-    // passing *something* for the unused parameter.
-    try {
-      ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent component =
-          DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent
-              .factory()
-              .create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/functional/factory/FactoryMixedParametersTest.java b/javatests/dagger/functional/factory/FactoryMixedParametersTest.java
deleted file mode 100644
index 733c673..0000000
--- a/javatests/dagger/functional/factory/FactoryMixedParametersTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import java.util.Random;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for component factories with multiple parameters. */
-@RunWith(JUnit4.class)
-public final class FactoryMixedParametersTest {
-
-  @Component(
-      modules = {
-        AbstractModule.class,
-        UninstantiableConcreteModule.class,
-        InstantiableConcreteModule.class
-      },
-      dependencies = Dependency.class)
-  interface MixedArgComponent {
-    String string();
-    int getInt();
-    long getLong();
-    Object object();
-    double getDouble();
-    Provider<Random> randomProvider();
-
-    @Component.Factory
-    interface Factory {
-      MixedArgComponent create(
-          @BindsInstance double d,
-          Dependency dependency,
-          UninstantiableConcreteModule module,
-          @BindsInstance Random random);
-    }
-  }
-
-  @Test
-  public void mixedArgComponent() {
-    Random random = new Random();
-    MixedArgComponent component =
-        DaggerFactoryMixedParametersTest_MixedArgComponent.factory()
-            .create(3.0, new Dependency(), new UninstantiableConcreteModule(2L), random);
-    assertThat(component.string()).isEqualTo("foo");
-    assertThat(component.getInt()).isEqualTo(42);
-    assertThat(component.getDouble()).isEqualTo(3.0);
-    assertThat(component.object()).isEqualTo("bar");
-    assertThat(component.getLong()).isEqualTo(2L);
-    assertThat(component.randomProvider().get()).isSameInstanceAs(random);
-    assertThat(component.randomProvider().get()).isSameInstanceAs(random);
-  }
-}
diff --git a/javatests/dagger/functional/factory/FactoryRequiredModulesTest.java b/javatests/dagger/functional/factory/FactoryRequiredModulesTest.java
deleted file mode 100644
index 5b81b51..0000000
--- a/javatests/dagger/functional/factory/FactoryRequiredModulesTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import dagger.Component;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for factories for components that have a module that must have an instance provided by the
- * user.
- */
-@RunWith(JUnit4.class)
-public final class FactoryRequiredModulesTest {
-
-  @Component(modules = UninstantiableConcreteModule.class)
-  interface UninstantiableConcreteModuleComponent {
-    long getLong();
-
-    @Component.Factory
-    interface Factory {
-      UninstantiableConcreteModuleComponent create(UninstantiableConcreteModule module);
-    }
-  }
-
-  @Test
-  public void uninstantiableConcreteModule() {
-    UninstantiableConcreteModuleComponent component =
-        DaggerFactoryRequiredModulesTest_UninstantiableConcreteModuleComponent.factory()
-            .create(new UninstantiableConcreteModule(42L));
-    assertThat(component.getLong()).isEqualTo(42L);
-  }
-
-  @Test
-  public void uninstantiableConcreteModule_failsOnNull() {
-    try {
-      DaggerFactoryRequiredModulesTest_UninstantiableConcreteModuleComponent.factory().create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/functional/factory/InstantiableConcreteModule.java b/javatests/dagger/functional/factory/InstantiableConcreteModule.java
deleted file mode 100644
index 37acbe0..0000000
--- a/javatests/dagger/functional/factory/InstantiableConcreteModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import dagger.Module;
-import dagger.Provides;
-
-@SuppressWarnings("StaticModuleMethods") // intentionally non-static
-@Module
-final class InstantiableConcreteModule {
-  @Provides
-  int provideInt() {
-    return 42;
-  }
-}
diff --git a/javatests/dagger/functional/factory/SubcomponentFactoryTest.java b/javatests/dagger/functional/factory/SubcomponentFactoryTest.java
deleted file mode 100644
index cbff8a1..0000000
--- a/javatests/dagger/functional/factory/SubcomponentFactoryTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.BindsInstance;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import javax.inject.Inject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@linkplain Subcomponent.Factory subcomponent factories}.
- *
- * <p>Most things are tested in {@code FactoryTest}; this is just intended to test some things like
- * injecting subcomponent factories and returning them from component methods.
- */
-@RunWith(JUnit4.class)
-public final class SubcomponentFactoryTest {
-
-  @Component
-  interface ParentWithSubcomponentFactory {
-    Sub.Factory subcomponentFactory();
-
-    @Component.Factory
-    interface Factory {
-      ParentWithSubcomponentFactory create(@BindsInstance int i);
-    }
-  }
-
-  @Subcomponent
-  interface Sub {
-    int i();
-    String s();
-
-    @Subcomponent.Factory
-    interface Factory {
-      Sub create(@BindsInstance String s);
-    }
-  }
-
-  @Test
-  public void parentComponentWithSubcomponentFactoryEntryPoint() {
-    ParentWithSubcomponentFactory parent =
-        DaggerSubcomponentFactoryTest_ParentWithSubcomponentFactory.factory().create(3);
-    Sub subcomponent = parent.subcomponentFactory().create("foo");
-    assertThat(subcomponent.i()).isEqualTo(3);
-    assertThat(subcomponent.s()).isEqualTo("foo");
-  }
-
-  @Module(subcomponents = Sub.class)
-  abstract static class ModuleWithSubcomponent {
-    @Provides
-    static int provideInt() {
-      return 42;
-    }
-  }
-
-  static class UsesSubcomponentFactory {
-    private final Sub.Factory subFactory;
-
-    @Inject
-    UsesSubcomponentFactory(Sub.Factory subFactory) {
-      this.subFactory = subFactory;
-    }
-
-    Sub getSubcomponent(String s) {
-      return subFactory.create(s);
-    }
-  }
-
-  @Component(modules = ModuleWithSubcomponent.class)
-  interface ParentWithModuleWithSubcomponent {
-    UsesSubcomponentFactory usesSubcomponentFactory();
-  }
-
-  @Test
-  public void parentComponentWithModuleWithSubcomponent() {
-    ParentWithModuleWithSubcomponent parent =
-        DaggerSubcomponentFactoryTest_ParentWithModuleWithSubcomponent.create();
-    UsesSubcomponentFactory usesSubcomponentFactory = parent.usesSubcomponentFactory();
-
-    Sub subcomponent1 = usesSubcomponentFactory.getSubcomponent("foo");
-    assertThat(subcomponent1.i()).isEqualTo(42);
-    assertThat(subcomponent1.s()).isEqualTo("foo");
-
-    Sub subcomponent2 = usesSubcomponentFactory.getSubcomponent("bar");
-    assertThat(subcomponent2.i()).isEqualTo(42);
-    assertThat(subcomponent2.s()).isEqualTo("bar");
-  }
-}
diff --git a/javatests/dagger/functional/factory/UninstantiableConcreteModule.java b/javatests/dagger/functional/factory/UninstantiableConcreteModule.java
deleted file mode 100644
index 13f50fd..0000000
--- a/javatests/dagger/functional/factory/UninstantiableConcreteModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.factory;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class UninstantiableConcreteModule {
-  private final long l;
-
-  UninstantiableConcreteModule(long l) {
-    this.l = l;
-  }
-
-  @Provides
-  long provideLong() {
-    return l;
-  }
-}
diff --git a/javatests/dagger/functional/guava/BUILD b/javatests/dagger/functional/guava/BUILD
deleted file mode 100644
index 66492eb..0000000
--- a/javatests/dagger/functional/guava/BUILD
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Functional tests for Dagger that depend on Guava
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "guava_tests",
-    srcs = glob(["**/*.java"]),
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr305_annotations",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/functional/guava/OptionalBindingComponents.java b/javatests/dagger/functional/guava/OptionalBindingComponents.java
deleted file mode 100644
index ee58865..0000000
--- a/javatests/dagger/functional/guava/OptionalBindingComponents.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.guava;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Optional;
-import dagger.BindsOptionalOf;
-import dagger.Component;
-import dagger.Lazy;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import java.lang.annotation.Retention;
-import javax.annotation.Nullable;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-/** Classes to support testing {@code BindsOptionalOf} functionality. */
-public final class OptionalBindingComponents {
-
-  /** A qualifier. */
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface SomeQualifier {}
-
-  /** A value object that contains various optionally-bound objects. */
-  @AutoValue
-  public abstract static class Values {
-    abstract Optional<Value> optionalInstance();
-
-    abstract Optional<Provider<Value>> optionalProvider();
-
-    abstract Optional<Lazy<Value>> optionalLazy();
-
-    abstract Optional<Provider<Lazy<Value>>> optionalLazyProvider();
-  }
-
-  // Default access so that it's inaccessible to OptionalBindingComponentsWithInaccessibleTypes.
-  enum Value {
-    VALUE,
-    QUALIFIED_VALUE
-  }
-
-  static final class InjectedThing {
-    @Inject
-    InjectedThing() {}
-  }
-
-  /** Binds optionals and {@link Values}. */
-  @Module
-  public abstract static class OptionalBindingModule {
-    @BindsOptionalOf
-    abstract Value value();
-
-    @BindsOptionalOf
-    @SomeQualifier abstract Value qualifiedValue();
-
-    // Valid because it's qualified.
-    @BindsOptionalOf
-    @SomeQualifier abstract InjectedThing qualifiedInjectedThing();
-
-    @BindsOptionalOf
-    abstract Object nullableObject();
-
-    @Provides
-    static Values values(
-        Optional<Value> optionalInstance,
-        Optional<Provider<Value>> optionalProvider,
-        Optional<Lazy<Value>> optionalLazy,
-        Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
-    }
-
-    @Provides
-    @SomeQualifier
-    static Values qualifiedValues(
-        @SomeQualifier Optional<Value> optionalInstance,
-        @SomeQualifier Optional<Provider<Value>> optionalProvider,
-        @SomeQualifier Optional<Lazy<Value>> optionalLazy,
-        @SomeQualifier Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
-    }
-  }
-
-  /** Binds {@link Value}. */
-  @Module
-  public abstract static class ConcreteBindingModule {
-    /** @param cycle to demonstrate that optional {@link Provider} injection can break cycles */
-    @Provides
-    static Value value(Optional<Provider<Value>> cycle) {
-      return Value.VALUE;
-    }
-
-    @Provides
-    @SomeQualifier static Value qualifiedValue() {
-      return Value.QUALIFIED_VALUE;
-    }
-
-    @Provides
-    @Nullable
-    static Object nullableObject() {
-      return null;
-    }
-  }
-
-  /** Interface for components used to test optional bindings. */
-  public interface OptionalBindingComponent {
-    Values values();
-
-    @SomeQualifier
-    Values qualifiedValues();
-
-    // Nullable bindings can satisfy optional bindings except for Optional<Foo>.
-
-    Optional<Provider<Object>> optionalNullableProvider();
-
-    Optional<Lazy<Object>> optionalNullableLazy();
-
-    Optional<Provider<Lazy<Object>>> optionalNullableLazyProvider();
-  }
-
-  @Component(modules = OptionalBindingModule.class)
-  interface AbsentOptionalBindingComponent extends OptionalBindingComponent {
-    PresentOptionalBindingSubcomponent presentChild();
-  }
-
-  @Component(modules = {OptionalBindingModule.class, ConcreteBindingModule.class})
-  interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
-
-  @Subcomponent(modules = ConcreteBindingModule.class)
-  interface PresentOptionalBindingSubcomponent extends OptionalBindingComponent {}
-}
diff --git a/javatests/dagger/functional/guava/OptionalBindingComponentsAbsentTest.java b/javatests/dagger/functional/guava/OptionalBindingComponentsAbsentTest.java
deleted file mode 100644
index d563ace..0000000
--- a/javatests/dagger/functional/guava/OptionalBindingComponentsAbsentTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.guava;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.guava.OptionalBindingComponents.AbsentOptionalBindingComponent;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for absent optional bindings. */
-@RunWith(JUnit4.class)
-public final class OptionalBindingComponentsAbsentTest {
-  private AbsentOptionalBindingComponent absent;
-
-  @Before
-  public void setUp() {
-    absent = DaggerOptionalBindingComponents_AbsentOptionalBindingComponent.create();
-  }
-
-  @Test
-  public void optional() {
-    assertThat(absent.values().optionalInstance()).isAbsent();
-  }
-
-  @Test
-  public void optionalProvider() {
-    assertThat(absent.values().optionalProvider()).isAbsent();
-  }
-
-  @Test
-  public void optionalLazy() {
-    assertThat(absent.values().optionalLazy()).isAbsent();
-  }
-
-  @Test
-  public void optionalLazyProvider() {
-    assertThat(absent.values().optionalLazyProvider()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptional() {
-    assertThat(absent.qualifiedValues().optionalInstance()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptionalProvider() {
-    assertThat(absent.qualifiedValues().optionalProvider()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptionalLazy() {
-    assertThat(absent.qualifiedValues().optionalLazy()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptionalLazyProvider() {
-    assertThat(absent.qualifiedValues().optionalLazyProvider()).isAbsent();
-  }
-}
diff --git a/javatests/dagger/functional/guava/OptionalBindingComponentsPresentTest.java b/javatests/dagger/functional/guava/OptionalBindingComponentsPresentTest.java
deleted file mode 100644
index 1243207..0000000
--- a/javatests/dagger/functional/guava/OptionalBindingComponentsPresentTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.guava;
-
-import static com.google.common.truth.Truth.assertThat;
-import static dagger.functional.guava.OptionalBindingComponents.Value.QUALIFIED_VALUE;
-import static dagger.functional.guava.OptionalBindingComponents.Value.VALUE;
-
-import com.google.common.collect.ImmutableList;
-import dagger.functional.guava.OptionalBindingComponents.OptionalBindingComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for present optional bindings. */
-@RunWith(Parameterized.class)
-public final class OptionalBindingComponentsPresentTest {
-
-  @Parameters(name = "{0}")
-  public static Iterable<Object[]> parameters() {
-    return ImmutableList.copyOf(
-        new Object[][] {
-          {DaggerOptionalBindingComponents_PresentOptionalBindingComponent.create()},
-          {DaggerOptionalBindingComponents_AbsentOptionalBindingComponent.create().presentChild()},
-        });
-  }
-
-  private final OptionalBindingComponent component;
-
-  public OptionalBindingComponentsPresentTest(OptionalBindingComponent component) {
-    this.component = component;
-  }
-
-  @Test
-  public void optionalProvider() {
-    assertThat(component.values().optionalProvider().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void optionalLazy() {
-    assertThat(component.values().optionalLazy().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void optionalLazyProvider() {
-    assertThat(component.values().optionalLazyProvider().get().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void qualifiedOptional() {
-    assertThat(component.qualifiedValues().optionalInstance()).hasValue(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalProvider() {
-    assertThat(component.qualifiedValues().optionalProvider().get().get())
-        .isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalLazy() {
-    assertThat(component.qualifiedValues().optionalLazy().get().get()).isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalLazyProvider() {
-    assertThat(component.qualifiedValues().optionalLazyProvider().get().get().get())
-        .isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void optionalNullableProvider() {
-    assertThat(component.optionalNullableProvider().get().get()).isNull();
-  }
-
-  @Test
-  public void optionalNullableLazy() {
-    assertThat(component.optionalNullableLazy().get().get()).isNull();
-  }
-
-  @Test
-  public void optionalNullableLazyProvider() {
-    assertThat(component.optionalNullableLazyProvider().get().get().get()).isNull();
-  }
-}
diff --git a/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypes.java b/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypes.java
deleted file mode 100644
index 28a6734..0000000
--- a/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypes.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.guava.a;
-
-import dagger.Component;
-import dagger.functional.guava.OptionalBindingComponents.ConcreteBindingModule;
-import dagger.functional.guava.OptionalBindingComponents.OptionalBindingComponent;
-import dagger.functional.guava.OptionalBindingComponents.OptionalBindingModule;
-
-final class OptionalBindingComponentsWithInaccessibleTypes {
-
-  @Component(modules = OptionalBindingModule.class)
-  interface AbsentOptionalBindingComponent extends OptionalBindingComponent {}
-
-  @Component(modules = {OptionalBindingModule.class, ConcreteBindingModule.class})
-  interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
-}
diff --git a/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypesTest.java b/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypesTest.java
deleted file mode 100644
index 6be593c..0000000
--- a/javatests/dagger/functional/guava/a/OptionalBindingComponentsWithInaccessibleTypesTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.guava.a;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for optional bindings that include types inaccessible to the component. */
-@RunWith(JUnit4.class)
-public class OptionalBindingComponentsWithInaccessibleTypesTest {
-  @Test
-  public void components() {
-    DaggerOptionalBindingComponentsWithInaccessibleTypes_AbsentOptionalBindingComponent.create();
-    DaggerOptionalBindingComponentsWithInaccessibleTypes_PresentOptionalBindingComponent.create();
-  }
-}
diff --git a/javatests/dagger/functional/gwt/GwtIncompatibles.java b/javatests/dagger/functional/gwt/GwtIncompatibles.java
deleted file mode 100644
index d65f116..0000000
--- a/javatests/dagger/functional/gwt/GwtIncompatibles.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.gwt;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.Module;
-import dagger.Provides;
-import java.lang.annotation.Retention;
-import javax.inject.Inject;
-
-interface GwtIncompatibles {
-  @Retention(RUNTIME)
-  @interface GwtIncompatible {}
-
-  @GwtIncompatible
-  class OnClass {
-    @Inject
-    OnClass() {}
-  }
-
-  class OnConstructor {
-    @Inject
-    @GwtIncompatible
-    OnConstructor() {}
-  }
-
-  @GwtIncompatible
-  class OuterClass {
-    static class OnOuterClass {
-      @Inject
-      OnOuterClass() {}
-    }
-  }
-
-  @GwtIncompatible
-  class MembersInjectedType {
-    @Inject String string;
-  }
-
-  @GwtIncompatible
-  @Module
-  class OnModule {
-    @Provides
-    static String onModule() {
-      return "on module";
-    }
-  }
-
-  @Module
-  class OnMethod {
-    @GwtIncompatible
-    @Provides
-    static String onMethod() {
-      return "on method";
-    }
-  }
-}
diff --git a/javatests/dagger/functional/gwt/GwtIncompatiblesTest.java b/javatests/dagger/functional/gwt/GwtIncompatiblesTest.java
deleted file mode 100644
index f6f6c41..0000000
--- a/javatests/dagger/functional/gwt/GwtIncompatiblesTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.gwt;
-
-import dagger.functional.gwt.GwtIncompatibles.GwtIncompatible;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@code @GwtIncompatible} bindings. */
-@RunWith(JUnit4.class)
-public class GwtIncompatiblesTest {
-  @Test
-  public void testIncompatible() {
-    assertGwtIncompatible(GwtIncompatibles_OnClass_Factory.class);
-    assertGwtIncompatible(GwtIncompatibles_OnConstructor_Factory.class);
-    assertGwtIncompatible(GwtIncompatibles_OuterClass_OnOuterClass_Factory.class);
-
-    assertGwtIncompatible(GwtIncompatibles_MembersInjectedType_MembersInjector.class);
-
-    assertGwtIncompatible(GwtIncompatibles_OnModule_OnModuleFactory.class);
-    assertGwtIncompatible(GwtIncompatibles_OnMethod_OnMethodFactory.class);
-  }
-
-  private void assertGwtIncompatible(Class<?> clazz) {
-    boolean gwtIncompatible = clazz.isAnnotationPresent(GwtIncompatible.class);
-    if (!gwtIncompatible) {
-      throw new AssertionError(clazz.getCanonicalName() + " is not @GwtIncompatible");
-    }
-  }
-}
diff --git a/javatests/dagger/functional/jdk8/BUILD b/javatests/dagger/functional/jdk8/BUILD
deleted file mode 100644
index 6b76ba3..0000000
--- a/javatests/dagger/functional/jdk8/BUILD
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Functional tests for Dagger that depend on Guava
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "jdk8_tests",
-    srcs = glob(["**/*.java"]),
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    test_only_deps = [
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth:truth8",
-    ],
-    deps = [
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/jsr305_annotations",
-    ],
-)
diff --git a/javatests/dagger/functional/jdk8/OptionalBindingComponents.java b/javatests/dagger/functional/jdk8/OptionalBindingComponents.java
deleted file mode 100644
index 0048f8b..0000000
--- a/javatests/dagger/functional/jdk8/OptionalBindingComponents.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.jdk8;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.auto.value.AutoValue;
-import dagger.BindsOptionalOf;
-import dagger.Component;
-import dagger.Lazy;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import java.lang.annotation.Retention;
-import java.util.Optional;
-import javax.annotation.Nullable;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-/** Classes to support testing {@code BindsOptionalOf} functionality. */
-public final class OptionalBindingComponents {
-
-  /** A qualifier. */
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface SomeQualifier {}
-
-  /** A value object that contains various optionally-bound objects. */
-  @AutoValue
-  public abstract static class Values {
-    abstract Optional<Value> optionalInstance();
-
-    abstract Optional<Provider<Value>> optionalProvider();
-
-    abstract Optional<Lazy<Value>> optionalLazy();
-
-    abstract Optional<Provider<Lazy<Value>>> optionalLazyProvider();
-  }
-
-  // Default access so that it's inaccessible to OptionalBindingComponentsWithInaccessibleTypes.
-  enum Value {
-    VALUE,
-    QUALIFIED_VALUE
-  }
-
-  static final class InjectedThing {
-    @Inject
-    InjectedThing() {}
-  }
-
-  /** Binds optionals and {@link Values}. */
-  @Module
-  public abstract static class OptionalBindingModule {
-    @BindsOptionalOf
-    abstract Value value();
-
-    @BindsOptionalOf
-    @SomeQualifier abstract Value qualifiedValue();
-
-    // Valid because it's qualified.
-    @BindsOptionalOf
-    @SomeQualifier abstract InjectedThing qualifiedInjectedThing();
-
-    @BindsOptionalOf
-    abstract Object nullableObject();
-
-    @Provides
-    static Values values(
-        Optional<Value> optionalInstance,
-        Optional<Provider<Value>> optionalProvider,
-        Optional<Lazy<Value>> optionalLazy,
-        Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
-    }
-
-    @Provides
-    @SomeQualifier
-    static Values qualifiedValues(
-        @SomeQualifier Optional<Value> optionalInstance,
-        @SomeQualifier Optional<Provider<Value>> optionalProvider,
-        @SomeQualifier Optional<Lazy<Value>> optionalLazy,
-        @SomeQualifier Optional<Provider<Lazy<Value>>> optionalLazyProvider) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProvider, optionalLazy, optionalLazyProvider);
-    }
-  }
-
-  /** Binds {@link Value}. */
-  @Module
-  public abstract static class ConcreteBindingModule {
-    /** @param cycle to demonstrate that optional {@link Provider} injection can break cycles */
-    @Provides
-    static Value value(Optional<Provider<Value>> cycle) {
-      return Value.VALUE;
-    }
-
-    @Provides
-    @SomeQualifier static Value qualifiedValue() {
-      return Value.QUALIFIED_VALUE;
-    }
-
-    @Provides
-    @Nullable
-    static Object nullableObject() {
-      return null;
-    }
-  }
-
-  /** Interface for components used to test optional bindings. */
-  public interface OptionalBindingComponent {
-    Values values();
-
-    @SomeQualifier
-    Values qualifiedValues();
-
-    // Nullable bindings can satisfy optional bindings except for Optional<Foo>.
-
-    Optional<Provider<Object>> optionalNullableProvider();
-
-    Optional<Lazy<Object>> optionalNullableLazy();
-
-    Optional<Provider<Lazy<Object>>> optionalNullableLazyProvider();
-  }
-
-  @Component(modules = OptionalBindingModule.class)
-  interface EmptyOptionalBindingComponent extends OptionalBindingComponent {
-    PresentOptionalBindingSubcomponent presentChild();
-  }
-
-  @Component(modules = {OptionalBindingModule.class, ConcreteBindingModule.class})
-  interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
-
-  @Subcomponent(modules = ConcreteBindingModule.class)
-  interface PresentOptionalBindingSubcomponent extends OptionalBindingComponent {}
-}
diff --git a/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java b/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java
deleted file mode 100644
index 21bdd3c..0000000
--- a/javatests/dagger/functional/jdk8/OptionalBindingComponentsEmptyTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.jdk8;
-
-import static com.google.common.truth.Truth8.assertThat;
-
-import dagger.functional.jdk8.OptionalBindingComponents.EmptyOptionalBindingComponent;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for absent optional bindings. */
-@RunWith(JUnit4.class)
-public final class OptionalBindingComponentsEmptyTest {
-  private EmptyOptionalBindingComponent component;
-
-  @Before
-  public void setUp() {
-    component = DaggerOptionalBindingComponents_EmptyOptionalBindingComponent.create();
-  }
-
-  @Test
-  public void optional() {
-    assertThat(component.values().optionalInstance()).isEmpty();
-  }
-
-  @Test
-  public void optionalProvider() {
-    assertThat(component.values().optionalProvider()).isEmpty();
-  }
-
-  @Test
-  public void optionalLazy() {
-    assertThat(component.values().optionalLazy()).isEmpty();
-  }
-
-  @Test
-  public void optionalLazyProvider() {
-    assertThat(component.values().optionalLazyProvider()).isEmpty();
-  }
-
-  @Test
-  public void qualifiedOptional() {
-    assertThat(component.qualifiedValues().optionalInstance()).isEmpty();
-  }
-
-  @Test
-  public void qualifiedOptionalProvider() {
-    assertThat(component.qualifiedValues().optionalProvider()).isEmpty();
-  }
-
-  @Test
-  public void qualifiedOptionalLazy() {
-    assertThat(component.qualifiedValues().optionalLazy()).isEmpty();
-  }
-
-  @Test
-  public void qualifiedOptionalLazyProvider() {
-    assertThat(component.qualifiedValues().optionalLazyProvider()).isEmpty();
-  }
-}
diff --git a/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java b/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java
deleted file mode 100644
index 50fbefe..0000000
--- a/javatests/dagger/functional/jdk8/OptionalBindingComponentsPresentTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.jdk8;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
-import static dagger.functional.jdk8.OptionalBindingComponents.Value.QUALIFIED_VALUE;
-import static dagger.functional.jdk8.OptionalBindingComponents.Value.VALUE;
-
-import com.google.common.collect.ImmutableList;
-import dagger.functional.jdk8.OptionalBindingComponents.OptionalBindingComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for present optional bindings. */
-@RunWith(Parameterized.class)
-public final class OptionalBindingComponentsPresentTest {
-
-  @Parameters(name = "{0}")
-  public static Iterable<Object[]> parameters() {
-    return ImmutableList.copyOf(
-        new Object[][] {
-          {DaggerOptionalBindingComponents_PresentOptionalBindingComponent.create()},
-          {DaggerOptionalBindingComponents_EmptyOptionalBindingComponent.create().presentChild()},
-        });
-  }
-
-  private final OptionalBindingComponent component;
-
-  public OptionalBindingComponentsPresentTest(OptionalBindingComponent component) {
-    this.component = component;
-  }
-
-  @Test
-  public void optionalProvider() {
-    assertThat(component.values().optionalProvider().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void optionalLazy() {
-    assertThat(component.values().optionalLazy().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void optionalLazyProvider() {
-    assertThat(component.values().optionalLazyProvider().get().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void qualifiedOptional() {
-    assertThat(component.qualifiedValues().optionalInstance()).hasValue(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalProvider() {
-    assertThat(component.qualifiedValues().optionalProvider().get().get())
-        .isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalLazy() {
-    assertThat(component.qualifiedValues().optionalLazy().get().get()).isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalLazyProvider() {
-    assertThat(component.qualifiedValues().optionalLazyProvider().get().get().get())
-        .isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void optionalNullableProvider() {
-    assertThat(component.optionalNullableProvider().get().get()).isNull();
-  }
-
-  @Test
-  public void optionalNullableLazy() {
-    assertThat(component.optionalNullableLazy().get().get()).isNull();
-  }
-
-  @Test
-  public void optionalNullableLazyProvider() {
-    assertThat(component.optionalNullableLazyProvider().get().get().get()).isNull();
-  }
-}
diff --git a/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypes.java b/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypes.java
deleted file mode 100644
index e4abbb6..0000000
--- a/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypes.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.jdk8.a;
-
-import dagger.Component;
-import dagger.functional.jdk8.OptionalBindingComponents.ConcreteBindingModule;
-import dagger.functional.jdk8.OptionalBindingComponents.OptionalBindingComponent;
-import dagger.functional.jdk8.OptionalBindingComponents.OptionalBindingModule;
-
-final class OptionalBindingComponentsWithInaccessibleTypes {
-
-  @Component(modules = OptionalBindingModule.class)
-  interface EmptyOptionalBindingComponent extends OptionalBindingComponent {}
-
-  @Component(modules = {OptionalBindingModule.class, ConcreteBindingModule.class})
-  interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
-}
diff --git a/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypesTest.java b/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypesTest.java
deleted file mode 100644
index 8e2687a..0000000
--- a/javatests/dagger/functional/jdk8/a/OptionalBindingComponentsWithInaccessibleTypesTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.jdk8.a;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for optional bindings that include types inaccessible to the component. */
-@RunWith(JUnit4.class)
-public class OptionalBindingComponentsWithInaccessibleTypesTest {
-  @Test
-  public void components() {
-    DaggerOptionalBindingComponentsWithInaccessibleTypes_EmptyOptionalBindingComponent.create();
-    DaggerOptionalBindingComponentsWithInaccessibleTypes_PresentOptionalBindingComponent.create();
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/ChildOfArrayOfParentOfStringArray.java b/javatests/dagger/functional/membersinject/ChildOfArrayOfParentOfStringArray.java
deleted file mode 100644
index 61bef71..0000000
--- a/javatests/dagger/functional/membersinject/ChildOfArrayOfParentOfStringArray.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-class ChildOfArrayOfParentOfStringArray extends
-    MembersInjectGenericParent<MembersInjectGenericParent<String[]>[]> {
-}
diff --git a/javatests/dagger/functional/membersinject/ChildOfPrimitiveIntArray.java b/javatests/dagger/functional/membersinject/ChildOfPrimitiveIntArray.java
deleted file mode 100644
index 154bcff..0000000
--- a/javatests/dagger/functional/membersinject/ChildOfPrimitiveIntArray.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-class ChildOfPrimitiveIntArray extends MembersInjectGenericParent<int[]> {
-
-}
diff --git a/javatests/dagger/functional/membersinject/ChildOfStringArray.java b/javatests/dagger/functional/membersinject/ChildOfStringArray.java
deleted file mode 100644
index d8bab7c..0000000
--- a/javatests/dagger/functional/membersinject/ChildOfStringArray.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-class ChildOfStringArray extends MembersInjectGenericParent<String[]> {
-
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectComponent.java b/javatests/dagger/functional/membersinject/MembersInjectComponent.java
deleted file mode 100644
index ed26113..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-import dagger.Component;
-
-@Component(modules = {MembersInjectModule.class})
-interface MembersInjectComponent {
-  
-  void inject(ChildOfStringArray subfoo);
-  void inject(ChildOfArrayOfParentOfStringArray subfoo);
-  void inject(ChildOfPrimitiveIntArray subfoo);
-  void inject(RawFrameworkTypes rawFrameworkTypes);
-
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectGenericParent.java b/javatests/dagger/functional/membersinject/MembersInjectGenericParent.java
deleted file mode 100644
index 3519348..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectGenericParent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-import javax.inject.Inject;
-
-class MembersInjectGenericParent<T> {
-  
-  @Inject T t; 
-
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectModule.java b/javatests/dagger/functional/membersinject/MembersInjectModule.java
deleted file mode 100644
index d60a7d1..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-class MembersInjectModule {
-  
-  @Provides String[] provideStringArray() { return new String[10]; }
-  
-  @Provides int[] provideIntArray() { return new int[10]; }
-  
-  @SuppressWarnings("unchecked")
-  @Provides MembersInjectGenericParent<String[]>[] provideFooArrayOfStringArray() { return new MembersInjectGenericParent[10]; }
-
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectTest.java b/javatests/dagger/functional/membersinject/MembersInjectTest.java
deleted file mode 100644
index 0617fd5..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.MembersInjector;
-import dagger.functional.multipackage.DaggerMembersInjectionVisibilityComponent;
-import dagger.functional.multipackage.MembersInjectionVisibilityComponent;
-import dagger.functional.multipackage.a.AGrandchild;
-import dagger.functional.multipackage.a.AParent;
-import dagger.functional.multipackage.b.BChild;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MembersInjectTest {
-  @Test public void testMembersInject_arrays() {
-    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
-
-    ChildOfStringArray childOfStringArray = new ChildOfStringArray();
-    component.inject(childOfStringArray);
-  }
-
-  @Test public void testMembersInject_nestedArrays() {
-    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
-
-    ChildOfArrayOfParentOfStringArray childOfArrayOfParentOfStringArray =
-        new ChildOfArrayOfParentOfStringArray();
-    component.inject(childOfArrayOfParentOfStringArray);
-  }
-
-  @Test public void testMembersInject_primitives() {
-    MembersInjectComponent component = DaggerMembersInjectComponent.builder().build();
-
-    ChildOfPrimitiveIntArray childOfPrimitiveIntArray = new ChildOfPrimitiveIntArray();
-    component.inject(childOfPrimitiveIntArray);
-  }
-
-  @Test
-  public void testMembersInject_overrides() {
-    MembersInjectionVisibilityComponent component =
-        DaggerMembersInjectionVisibilityComponent.create();
-    AParent aParent = new AParent();
-    component.inject(aParent);
-    assertThat(aParent.aParentField()).isNotNull();
-    assertThat(aParent.aParentMethod()).isNotNull();
-
-    BChild aChild = new BChild();
-    component.inject(aChild);
-    assertThat(aChild.aParentField()).isNotNull();
-    assertThat(aChild.aParentMethod()).isNull();
-    assertThat(aChild.aChildField()).isNotNull();
-    assertThat(aChild.aChildMethod()).isNotNull();
-
-    AGrandchild aGrandchild = new AGrandchild();
-    component.inject(aGrandchild);
-    assertThat(aGrandchild.aParentField()).isNotNull();
-    assertThat(aGrandchild.aParentMethod()).isNotNull();
-    assertThat(aGrandchild.aChildField()).isNotNull();
-    assertThat(aGrandchild.aChildMethod()).isNull();
-    assertThat(aGrandchild.aGrandchildField()).isNotNull();
-    assertThat(aGrandchild.aGrandchildMethod()).isNotNull();
-  }
-
-  @Test
-  public void testNonRequestedMembersInjector() {
-    NonRequestedChild child = new NonRequestedChild();
-    Provider<String> provider =
-        new Provider<String>() {
-          @Override
-          public String get() {
-            return "field!";
-          }
-        };
-    MembersInjector<NonRequestedChild> injector = new NonRequestedChild_MembersInjector(provider);
-    injector.injectMembers(child);
-    assertThat(child.t).isEqualTo("field!");
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectionOrdering.java b/javatests/dagger/functional/membersinject/MembersInjectionOrdering.java
deleted file mode 100644
index 451e0e3..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectionOrdering.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.membersinject;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import javax.inject.Inject;
-
-/**
- * This exhibits a regression case, that albeit weird, is valid according to the JSR 330 spec. JSR
- * 330 specifies a rough ordering by which members should be injected, and it is possible to rely on
- * such ordering. When members injecting {@link Subtype}, field injection is guaranteed to be
- * performed on {@link Base} first. The binding for {@code @FirstToString} in {@link
- * OrderingModule#provideToString()} relies on this ordering, and thus uses the value in {@link
- * Base#first} to satisfy the binding.
- */
-class MembersInjectionOrdering {
-  static class Base {
-    @Inject First first;
-  }
-
-  static class Subtype extends Base {
-    @Inject String firstToString;
-  }
-
-  @Module
-  static class OrderingModule {
-    private final Subtype subtype;
-
-    OrderingModule(Subtype subtype) {
-      this.subtype = subtype;
-    }
-
-    @Provides
-    String provideToString() {
-      return subtype.first.toString();
-    }
-  }
-
-  @Component(modules = OrderingModule.class)
-  interface TestComponent {
-    void inject(Subtype subtype);
-  }
-
-  static class First {
-    @Inject
-    First() {}
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/MembersInjectionOrderingTest.java b/javatests/dagger/functional/membersinject/MembersInjectionOrderingTest.java
deleted file mode 100644
index efd5117..0000000
--- a/javatests/dagger/functional/membersinject/MembersInjectionOrderingTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.membersinject;
-
-import dagger.functional.membersinject.MembersInjectionOrdering.OrderingModule;
-import dagger.functional.membersinject.MembersInjectionOrdering.Subtype;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MembersInjectionOrderingTest {
-  @Test
-  public void indirection() {
-    Subtype toInject = new Subtype();
-    DaggerMembersInjectionOrdering_TestComponent.builder()
-        .orderingModule(new OrderingModule(toInject))
-        .build()
-        .inject(toInject);
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/MembersWithSameName.java b/javatests/dagger/functional/membersinject/MembersWithSameName.java
deleted file mode 100644
index 2b06898..0000000
--- a/javatests/dagger/functional/membersinject/MembersWithSameName.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.membersinject;
-
-import javax.inject.Inject;
-
-// https://github.com/google/dagger/issues/755
-public class MembersWithSameName {
-  @Inject String sameName;
-  boolean sameNameStringWasInvoked;
-  boolean sameNameObjectWasInvoked;
-
-  @Inject void sameName(String sameName) {
-    sameNameStringWasInvoked = true;
-  }
-
-  @Inject void sameName(Object sameName) {
-    sameNameObjectWasInvoked = true;
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/MembersWithSameNameTest.java b/javatests/dagger/functional/membersinject/MembersWithSameNameTest.java
deleted file mode 100644
index 0f22bf3..0000000
--- a/javatests/dagger/functional/membersinject/MembersWithSameNameTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.membersinject;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.functional.membersinject.subpackage.ExtendsMembersWithSameName;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-// https://github.com/google/dagger/issues/755
-@RunWith(JUnit4.class)
-public class MembersWithSameNameTest {
-  @Test
-  public void injectsMaskedMembers() {
-    MembersWithSameName membersWithSameName = new MembersWithSameName();
-    TestComponent component = DaggerMembersWithSameNameTest_TestComponent.create();
-    component.inject(membersWithSameName);
-    verifyBaseClassInjection(membersWithSameName);
-  }
-
-  @Test
-  public void subclassInjectsMaskedMembers() {
-    ExtendsMembersWithSameName extendsMembersWithSameName = new ExtendsMembersWithSameName();
-    TestComponent component = DaggerMembersWithSameNameTest_TestComponent.create();
-    component.inject(extendsMembersWithSameName);
-    verifyBaseClassInjection(extendsMembersWithSameName);
-    verifySubclassInjection(extendsMembersWithSameName);
-  }
-
-  private void verifyBaseClassInjection(MembersWithSameName membersWithSameName) {
-    assertThat(membersWithSameName.sameName).isNotNull();
-    assertThat(membersWithSameName.sameNameStringWasInvoked).isTrue();
-    assertThat(membersWithSameName.sameNameObjectWasInvoked).isTrue();
-  }
-
-  private void verifySubclassInjection(ExtendsMembersWithSameName extendsMembersWithSameName) {
-    assertThat(extendsMembersWithSameName.sameName()).isNotNull();
-    assertThat(extendsMembersWithSameName.sameNameStringWasInvoked()).isTrue();
-    assertThat(extendsMembersWithSameName.sameNameObjectWasInvoked()).isTrue();
-  }
-
-  @Module
-  abstract static class TestModule {
-    @Provides
-    static String provideString() {
-      return "";
-    }
-
-    @Binds
-    abstract Object bindObject(String string);
-  }
-
-  @Component(modules = TestModule.class)
-  interface TestComponent {
-    void inject(MembersWithSameName membersWithSameName);
-    void inject(ExtendsMembersWithSameName extendsMembersWithSameName);
-  }
-}
diff --git a/javatests/dagger/functional/membersinject/NonRequestedChild.java b/javatests/dagger/functional/membersinject/NonRequestedChild.java
deleted file mode 100644
index a060473..0000000
--- a/javatests/dagger/functional/membersinject/NonRequestedChild.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.membersinject;
-
-import javax.inject.Inject;
-
-/**
- * A class that should not be requested by any component, to ensure that we still generate a members
- * injector for it.
- */
-class NonRequestedChild extends MembersInjectGenericParent<String> {
-  @Inject
-  NonRequestedChild() {}
-}
diff --git a/javatests/dagger/functional/membersinject/RawFrameworkTypes.java b/javatests/dagger/functional/membersinject/RawFrameworkTypes.java
deleted file mode 100644
index 2180613..0000000
--- a/javatests/dagger/functional/membersinject/RawFrameworkTypes.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.membersinject;
-
-import dagger.Lazy;
-import dagger.MembersInjector;
-import javax.inject.Provider;
-
-// https://github.com/google/dagger/issues/419
-@SuppressWarnings({"rawtypes", "unused"})
-class RawFrameworkTypes {
-  void nonInjectMethodWithARawProvider(Provider rawProvider) {}
-  void nonInjectMethodWithARawLazy(Lazy rawLazy) {}
-  void nonInjectMethodWithARawMembersInjector(MembersInjector rawMembersInjector) {}
-}
diff --git a/javatests/dagger/functional/membersinject/subpackage/ExtendsMembersWithSameName.java b/javatests/dagger/functional/membersinject/subpackage/ExtendsMembersWithSameName.java
deleted file mode 100644
index 1eb1b15..0000000
--- a/javatests/dagger/functional/membersinject/subpackage/ExtendsMembersWithSameName.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.membersinject.subpackage;
-
-import dagger.functional.membersinject.MembersWithSameName;
-import javax.inject.Inject;
-
-// https://github.com/google/dagger/issues/755
-public class ExtendsMembersWithSameName extends MembersWithSameName {
-  @Inject String sameName;
-  private boolean sameNameStringWasInvoked;
-  private boolean sameNameObjectWasInvoked;
-
-  @Inject void sameName(String sameName) {
-    sameNameStringWasInvoked = true;
-  }
-
-  @Inject void sameName(Object sameName) {
-    sameNameObjectWasInvoked = true;
-  }
-
-  public String sameName() {
-    return sameName;
-  }
-  public boolean sameNameStringWasInvoked() {
-    return sameNameStringWasInvoked;
-  }
-  public boolean sameNameObjectWasInvoked() {
-    return sameNameObjectWasInvoked;
-  }
-}
diff --git a/javatests/dagger/functional/modules/ModuleIncludesTest.java b/javatests/dagger/functional/modules/ModuleIncludesTest.java
deleted file mode 100644
index 38f7d97..0000000
--- a/javatests/dagger/functional/modules/ModuleIncludesTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.modules;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Component;
-import dagger.functional.modules.subpackage.PublicModule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ModuleIncludesTest {
-
-  @Component(modules = PublicModule.class)
-  interface TestComponent {
-    Object object();
-  }
-
-  @Test
-  public void publicModuleIncludingPackagePrivateModuleThatDoesNotRequireInstance() {
-    TestComponent component = DaggerModuleIncludesTest_TestComponent.create();
-    assertThat(component.object()).isEqualTo("foo42");
-  }
-}
diff --git a/javatests/dagger/functional/modules/subpackage/PackagePrivateModule.java b/javatests/dagger/functional/modules/subpackage/PackagePrivateModule.java
deleted file mode 100644
index 66852d7..0000000
--- a/javatests/dagger/functional/modules/subpackage/PackagePrivateModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.modules.subpackage;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-abstract class PackagePrivateModule {
-  @Binds
-  abstract Object bindObject(String string);
-
-  @Provides
-  static String provideString(int i) {
-    return "foo" + i;
-  }
-}
diff --git a/javatests/dagger/functional/modules/subpackage/PublicModule.java b/javatests/dagger/functional/modules/subpackage/PublicModule.java
deleted file mode 100644
index 7c5fd29..0000000
--- a/javatests/dagger/functional/modules/subpackage/PublicModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.modules.subpackage;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module(includes = PackagePrivateModule.class)
-public abstract class PublicModule {
-  @Provides
-  static int provideInt() {
-    return 42;
-  }
-}
diff --git a/javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java b/javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java
deleted file mode 100644
index 6256812..0000000
--- a/javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multibindings;
-
-import dagger.Component;
-import dagger.functional.multibindings.subpackage.BindsInaccessibleMapKeyModule;
-import java.util.Map;
-
-// b/73820357
-@Component(modules = BindsInaccessibleMapKeyModule.class)
-interface BindsInaccessibleMapKey {
-  Map<Class<?>, Object> mapWithAnInaccessibleMapKey();
-}
diff --git a/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java b/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java
deleted file mode 100644
index f2b5598..0000000
--- a/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multibindings;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.auto.value.AutoAnnotation;
-import dagger.Component;
-import dagger.MapKey;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import java.util.Map;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ComplexMapKeysInDifferentOrderTest {
-  @MapKey(unwrapValue = false)
-  @interface ComplexMapKey {
-    int i();
-    int j();
-  }
-
-  @Module
-  interface TestModule {
-    @Provides
-    @IntoMap
-    @ComplexMapKey(i = 1, j = 2)
-    static int inOrder() {
-      return 3;
-    }
-
-    @Provides
-    @IntoMap
-    @ComplexMapKey(j = 4, i = 5)
-    static int backwardsOrder() {
-      return 6;
-    }
-  }
-
-  @Component(modules = TestModule.class)
-  interface TestComponent {
-    Map<ComplexMapKey, Integer> map();
-  }
-
-  @Test
-  public void test() {
-    Map<ComplexMapKey, Integer> map =
-        DaggerComplexMapKeysInDifferentOrderTest_TestComponent.create().map();
-    assertThat(map.get(mapKey(1, 2))).isEqualTo(3);
-    assertThat(map.get(mapKey(5, 4))).isEqualTo(6);
-  }
-
-  @AutoAnnotation
-  static ComplexMapKey mapKey(int i, int j) {
-    return new AutoAnnotation_ComplexMapKeysInDifferentOrderTest_mapKey(i, j);
-  }
-}
diff --git a/javatests/dagger/functional/multibindings/MapKeyWithDefaultTest.java b/javatests/dagger/functional/multibindings/MapKeyWithDefaultTest.java
deleted file mode 100644
index f188405..0000000
--- a/javatests/dagger/functional/multibindings/MapKeyWithDefaultTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multibindings;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.auto.value.AutoAnnotation;
-import dagger.Component;
-import dagger.MapKey;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import java.util.Map;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class MapKeyWithDefaultTest {
-  @MapKey(unwrapValue = false)
-  @interface MapKeyWithDefault {
-    boolean hasDefault() default true;
-    boolean required();
-  }
-
-  @Module
-  interface TestModule {
-    @Provides
-    @IntoMap
-    @MapKeyWithDefault(required = false)
-    static int justRequired() {
-      return 1;
-    }
-
-    @Provides
-    @IntoMap
-    @MapKeyWithDefault(required = false, hasDefault = false)
-    static int both() {
-      return 2;
-    }
-  }
-
-  @Component(modules = TestModule.class)
-  interface TestComponent {
-    Map<MapKeyWithDefault, Integer> map();
-  }
-
-  @Test
-  public void test() {
-    Map<MapKeyWithDefault, Integer> map = DaggerMapKeyWithDefaultTest_TestComponent.create().map();
-    assertThat(map).hasSize(2);
-    assertThat(map.get(mapKey(true, false))).isEqualTo(1);
-    assertThat(map.get(mapKey(false, false))).isEqualTo(2);
-  }
-
-  @AutoAnnotation
-  static MapKeyWithDefault mapKey(boolean hasDefault, boolean required) {
-    return new AutoAnnotation_MapKeyWithDefaultTest_mapKey(hasDefault, required);
-  }
-}
diff --git a/javatests/dagger/functional/multibindings/subpackage/BindsInaccessibleMapKeyModule.java b/javatests/dagger/functional/multibindings/subpackage/BindsInaccessibleMapKeyModule.java
deleted file mode 100644
index 62df4ae..0000000
--- a/javatests/dagger/functional/multibindings/subpackage/BindsInaccessibleMapKeyModule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multibindings.subpackage;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-import javax.inject.Inject;
-
-@Module
-public abstract class BindsInaccessibleMapKeyModule {
-  @Binds
-  @IntoMap
-  @ClassKey(Inaccessible.class)
-  abstract Object bindInaccessibleMapKey(Inaccessible inaccessible);
-
-  static class Inaccessible {
-    @Inject Inaccessible() {}
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/FooComponent.java b/javatests/dagger/functional/multipackage/FooComponent.java
deleted file mode 100644
index ef5b8d5..0000000
--- a/javatests/dagger/functional/multipackage/FooComponent.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage;
-
-import dagger.Component;
-import dagger.functional.multipackage.a.AModule;
-import dagger.functional.multipackage.a.UsesInaccessible;
-import dagger.functional.multipackage.a.UsesInaccessibleInGenericsOnly;
-import dagger.functional.multipackage.sub.FooChildComponent;
-import java.util.Set;
-
-/**
- * A component that tests the interaction between subcomponents, multiple packages, and
- * multibindings. Specifically, we want:
- * <ul>
- * <li>A set binding with some contributions in the parent component, and some in the subcomponent.
- * <li>The contributions come from different packages, but not the package of either component.
- * <li>The set binding is requested in the subcomponent through a binding from a separate package.
- * <li>No binding in the subcomponent, that's in the subcomponent's package, directly uses any
- *     binding from the component's package.
- * </ul>
- */
-// NOTE(beder): Be careful about changing any bindings in either this component or the subcomponent.
-// Even adding a binding might stop this test from testing what it's supposed to test.
-@Component(modules = {AModule.class})
-interface FooComponent {
-  Set<String> setOfString();
-
-  FooChildComponent fooChildComponent();
-
-  UsesInaccessible usesInaccessible();
-
-  UsesInaccessibleInGenericsOnly accessibleConstructorUsesInaccessibleInGenericsOnly();
-}
diff --git a/javatests/dagger/functional/multipackage/MembersInjectionVisibilityComponent.java b/javatests/dagger/functional/multipackage/MembersInjectionVisibilityComponent.java
deleted file mode 100644
index 32b9c5e..0000000
--- a/javatests/dagger/functional/multipackage/MembersInjectionVisibilityComponent.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage;
-
-import dagger.Component;
-import dagger.functional.multipackage.a.AGrandchild;
-import dagger.functional.multipackage.a.AModule;
-import dagger.functional.multipackage.a.AParent;
-import dagger.functional.multipackage.b.BChild;
-
-/**
- * A component that tests members injection across packages and subclasses.
- */
-@Component(modules = {AModule.class})
-public interface MembersInjectionVisibilityComponent {
-  void inject(AParent aParent);
-
-  void inject(BChild aChild);
-
-  void inject(AGrandchild aGrandchild);
-}
diff --git a/javatests/dagger/functional/multipackage/MultibindsComponent.java b/javatests/dagger/functional/multipackage/MultibindsComponent.java
deleted file mode 100644
index dbeeed8..0000000
--- a/javatests/dagger/functional/multipackage/MultibindsComponent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.multipackage;
-
-import dagger.Component;
-import dagger.functional.multipackage.a.AMultibindsModule;
-import dagger.functional.multipackage.a.UsesInaccessible;
-
-/**
- * A component that tests the interaction between multiple packages and {@code @Multibinding}s.
- * Specifically, we want:
- *
- * <ul>
- * <li>A {@code @Multibinding} for an empty set of a type not accessible from this package.
- * <li>A {@code @Multibinding} for an empty map of a type not accessible from this package.
- * <li>A public type that injects the empty set and map of inaccessible objects.
- * </ul>
- */
-@Component(modules = {AMultibindsModule.class})
-interface MultibindsComponent {
-  UsesInaccessible usesInaccessible();
-}
diff --git a/javatests/dagger/functional/multipackage/PrimitivesAcrossPackagesComponent.java b/javatests/dagger/functional/multipackage/PrimitivesAcrossPackagesComponent.java
deleted file mode 100644
index 639558f..0000000
--- a/javatests/dagger/functional/multipackage/PrimitivesAcrossPackagesComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multipackage;
-
-import dagger.Component;
-import dagger.functional.multipackage.primitives.PrimitiveAcrossPackagesModule;
-import javax.inject.Provider;
-
-// b/77150738#comment11
-@Component(modules = PrimitiveAcrossPackagesModule.class)
-interface PrimitivesAcrossPackagesComponent {
-  boolean primitive();
-
-  Provider<Boolean> boxedPrimitive();
-}
diff --git a/javatests/dagger/functional/multipackage/UsesModuleWithInaccessibleConstructor.java b/javatests/dagger/functional/multipackage/UsesModuleWithInaccessibleConstructor.java
deleted file mode 100644
index 7764112..0000000
--- a/javatests/dagger/functional/multipackage/UsesModuleWithInaccessibleConstructor.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multipackage;
-
-import dagger.Component;
-import dagger.functional.multipackage.moduleconstructor.ModuleWithInaccessibleConstructor;
-
-@Component(modules = ModuleWithInaccessibleConstructor.class)
-public interface UsesModuleWithInaccessibleConstructor {
-  int i();
-}
diff --git a/javatests/dagger/functional/multipackage/a/AGrandchild.java b/javatests/dagger/functional/multipackage/a/AGrandchild.java
deleted file mode 100644
index ffb03d5..0000000
--- a/javatests/dagger/functional/multipackage/a/AGrandchild.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import dagger.functional.multipackage.b.BChild;
-import javax.inject.Inject;
-
-public class AGrandchild extends BChild {
-
-  @Inject APackagePrivateObject aGrandchildField;
-
-  private APackagePrivateObject aGrandchildMethod;
-
-  @Inject
-  void aGrandchildMethod(APackagePrivateObject aGrandchildMethod) {
-    this.aGrandchildMethod = aGrandchildMethod;
-  }
-
-  @Override
-  @Inject
-  protected void aParentMethod(APublicObject aParentMethod) {
-    super.aParentMethod(aParentMethod);
-  }
-
-  @SuppressWarnings("OverridesJavaxInjectableMethod")
-  @Override
-  protected void aChildMethod(APublicObject aChildMethod) {
-    super.aChildMethod(aChildMethod);
-  }
-
-  public APackagePrivateObject aGrandchildField() {
-    return aGrandchildField;
-  }
-
-  public APackagePrivateObject aGrandchildMethod() {
-    return aGrandchildMethod;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/a/AModule.java b/javatests/dagger/functional/multipackage/a/AModule.java
deleted file mode 100644
index 9f6a7c5..0000000
--- a/javatests/dagger/functional/multipackage/a/AModule.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.multibindings.StringKey;
-import java.util.HashSet;
-import java.util.Set;
-
-@Module
-public abstract class AModule {
-  @Provides
-  @IntoSet
-  static String provideString() {
-    return "a";
-  }
-
-  @Binds
-  @IntoSet
-  abstract Inaccessible provideInaccessible(Inaccessible inaccessible);
-
-  @Provides
-  @ElementsIntoSet
-  static Set<Inaccessible> provideSetOfInaccessibles() {
-    return new HashSet<>();
-  }
-
-  @Binds
-  @IntoMap
-  @StringKey("inaccessible")
-  abstract Inaccessible provideInaccessibleToMap(Inaccessible inaccessible);
-}
diff --git a/javatests/dagger/functional/multipackage/a/AMultibindsModule.java b/javatests/dagger/functional/multipackage/a/AMultibindsModule.java
deleted file mode 100644
index bcf28c9..0000000
--- a/javatests/dagger/functional/multipackage/a/AMultibindsModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import dagger.Module;
-import dagger.multibindings.Multibinds;
-import java.util.Map;
-import java.util.Set;
-
-/** A module that {@code @Multibinds} a set and a map of {@link Inaccessible}. */
-@Module
-public abstract class AMultibindsModule {
-  @Multibinds
-  abstract Set<Inaccessible> inaccessibleSet();
-
-  @Multibinds
-  abstract Map<String, Inaccessible> inaccessibleMap();
-}
diff --git a/javatests/dagger/functional/multipackage/a/APackagePrivateObject.java b/javatests/dagger/functional/multipackage/a/APackagePrivateObject.java
deleted file mode 100644
index f674b82..0000000
--- a/javatests/dagger/functional/multipackage/a/APackagePrivateObject.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import javax.inject.Inject;
-
-class APackagePrivateObject {
-
-  @Inject
-  APackagePrivateObject() {}
-}
diff --git a/javatests/dagger/functional/multipackage/a/AParent.java b/javatests/dagger/functional/multipackage/a/AParent.java
deleted file mode 100644
index de99ffd..0000000
--- a/javatests/dagger/functional/multipackage/a/AParent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import javax.inject.Inject;
-
-public class AParent {
-
-  @Inject APackagePrivateObject aParentField;
-
-  private APublicObject aParentMethod;
-
-  @Inject
-  protected void aParentMethod(APublicObject aParentMethod) {
-    this.aParentMethod = aParentMethod;
-  }
-
-  public APackagePrivateObject aParentField() {
-    return aParentField;
-  }
-
-  public APublicObject aParentMethod() {
-    return aParentMethod;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/a/APublicObject.java b/javatests/dagger/functional/multipackage/a/APublicObject.java
deleted file mode 100644
index 6c85721..0000000
--- a/javatests/dagger/functional/multipackage/a/APublicObject.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.a;
-
-import javax.inject.Inject;
-
-public class APublicObject {
-
-  @Inject
-  APublicObject() {}
-}
diff --git a/javatests/dagger/functional/multipackage/a/Inaccessible.java b/javatests/dagger/functional/multipackage/a/Inaccessible.java
deleted file mode 100644
index 30e2861..0000000
--- a/javatests/dagger/functional/multipackage/a/Inaccessible.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.multipackage.a;
-
-import javax.inject.Inject;
-
-final class Inaccessible {
-  @Inject Inaccessible() {}
-}
\ No newline at end of file
diff --git a/javatests/dagger/functional/multipackage/a/InaccessibleGeneric.java b/javatests/dagger/functional/multipackage/a/InaccessibleGeneric.java
deleted file mode 100644
index f5da79d..0000000
--- a/javatests/dagger/functional/multipackage/a/InaccessibleGeneric.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.multipackage.a;
-
-import javax.inject.Inject;
-
-final class InaccessibleGeneric<T> {
-  @Inject
-  InaccessibleGeneric() {}
-}
diff --git a/javatests/dagger/functional/multipackage/a/UsesInaccessible.java b/javatests/dagger/functional/multipackage/a/UsesInaccessible.java
deleted file mode 100644
index 7a8ed7f..0000000
--- a/javatests/dagger/functional/multipackage/a/UsesInaccessible.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.multipackage.a;
-
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Inject;
-
-@SuppressWarnings("unused")
-public class UsesInaccessible {
-  @Inject
-  public UsesInaccessible(
-      Inaccessible inaccessible,
-      Set<Inaccessible> inaccessibleSet,
-      Map<String, Inaccessible> inaccessibleMap,
-      InaccessibleGeneric<Integer> inaccessibleGeneric) {}
-}
diff --git a/javatests/dagger/functional/multipackage/a/UsesInaccessibleInGenericsOnly.java b/javatests/dagger/functional/multipackage/a/UsesInaccessibleInGenericsOnly.java
deleted file mode 100644
index a69aa56..0000000
--- a/javatests/dagger/functional/multipackage/a/UsesInaccessibleInGenericsOnly.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.multipackage.a;
-
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Inject;
-
-@SuppressWarnings("unused")
-public class UsesInaccessibleInGenericsOnly {
-  @Inject
-  public UsesInaccessibleInGenericsOnly(
-      Set<Inaccessible> inaccessibleSet, Map<String, Inaccessible> inaccessibleMap) {}
-}
diff --git a/javatests/dagger/functional/multipackage/b/BChild.java b/javatests/dagger/functional/multipackage/b/BChild.java
deleted file mode 100644
index fe5da66..0000000
--- a/javatests/dagger/functional/multipackage/b/BChild.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.b;
-
-import dagger.functional.multipackage.a.AParent;
-import dagger.functional.multipackage.a.APublicObject;
-import javax.inject.Inject;
-
-public class BChild extends AParent {
-
-  @Inject BPackagePrivateObject aChildField;
-
-  private APublicObject aChildMethod;
-
-  @Inject
-  protected void aChildMethod(APublicObject aChildMethod) {
-    this.aChildMethod = aChildMethod;
-  }
-
-  @SuppressWarnings("OverridesJavaxInjectableMethod")
-  @Override
-  protected void aParentMethod(APublicObject aParentMethod) {
-    super.aParentMethod(aParentMethod);
-  }
-
-  public BPackagePrivateObject aChildField() {
-    return aChildField;
-  }
-
-  public APublicObject aChildMethod() {
-    return aChildMethod;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/b/BModule.java b/javatests/dagger/functional/multipackage/b/BModule.java
deleted file mode 100644
index 6edf4bf..0000000
--- a/javatests/dagger/functional/multipackage/b/BModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.b;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-public final class BModule {
-  @Provides
-  @IntoSet
-  static String provideString() {
-    return "b";
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/b/BPackagePrivateObject.java b/javatests/dagger/functional/multipackage/b/BPackagePrivateObject.java
deleted file mode 100644
index b785a4a..0000000
--- a/javatests/dagger/functional/multipackage/b/BPackagePrivateObject.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.b;
-
-import javax.inject.Inject;
-
-class BPackagePrivateObject {
-
-  @Inject
-  BPackagePrivateObject() {}
-}
diff --git a/javatests/dagger/functional/multipackage/c/CModule.java b/javatests/dagger/functional/multipackage/c/CModule.java
deleted file mode 100644
index df257ad..0000000
--- a/javatests/dagger/functional/multipackage/c/CModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.c;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-public final class CModule {
-  @Provides
-  @IntoSet
-  static String provideString() {
-    return "c";
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/d/DModule.java b/javatests/dagger/functional/multipackage/d/DModule.java
deleted file mode 100644
index c98d647..0000000
--- a/javatests/dagger/functional/multipackage/d/DModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.d;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-public final class DModule {
-  @Provides
-  @IntoSet
-  static String provideString() {
-    return "d";
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/foo/Foo.java b/javatests/dagger/functional/multipackage/foo/Foo.java
deleted file mode 100644
index 1c06aa5..0000000
--- a/javatests/dagger/functional/multipackage/foo/Foo.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.foo;
-
-import java.util.Set;
-import javax.inject.Inject;
-
-public final class Foo<T> {
-  public final Set<String> strings;
-
-  @Inject Foo(Set<String> strings) {
-    this.strings = strings;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/grandsub/FooGrandchildComponent.java b/javatests/dagger/functional/multipackage/grandsub/FooGrandchildComponent.java
deleted file mode 100644
index 171b92a..0000000
--- a/javatests/dagger/functional/multipackage/grandsub/FooGrandchildComponent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.grandsub;
-
-import dagger.Subcomponent;
-import dagger.functional.multipackage.d.DModule;
-import dagger.functional.multipackage.foo.Foo;
-
-@Subcomponent(modules = DModule.class)
-public interface FooGrandchildComponent {
-  Foo<FooGrandchildComponent> foo();
-}
diff --git a/javatests/dagger/functional/multipackage/moduleconstructor/ModuleWithInaccessibleConstructor.java b/javatests/dagger/functional/multipackage/moduleconstructor/ModuleWithInaccessibleConstructor.java
deleted file mode 100644
index 6ca0074..0000000
--- a/javatests/dagger/functional/multipackage/moduleconstructor/ModuleWithInaccessibleConstructor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multipackage.moduleconstructor;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.Random;
-
-@Module
-public class ModuleWithInaccessibleConstructor {
-  private final int i;
-
-  /* intentionally package private */ModuleWithInaccessibleConstructor() {
-    i = new Random().nextInt();
-  }
-
-  @Provides
-  int i() {
-    return i;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/primitives/PrimitiveAcrossPackagesModule.java b/javatests/dagger/functional/multipackage/primitives/PrimitiveAcrossPackagesModule.java
deleted file mode 100644
index 1e6e362..0000000
--- a/javatests/dagger/functional/multipackage/primitives/PrimitiveAcrossPackagesModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.multipackage.primitives;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public final class PrimitiveAcrossPackagesModule {
-  // This method should be package-private so that a proxy method is created
-  @Provides
-  static boolean primitive() {
-    return false;
-  }
-}
diff --git a/javatests/dagger/functional/multipackage/sub/FooChildComponent.java b/javatests/dagger/functional/multipackage/sub/FooChildComponent.java
deleted file mode 100644
index b4f1389..0000000
--- a/javatests/dagger/functional/multipackage/sub/FooChildComponent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.multipackage.sub;
-
-import dagger.Subcomponent;
-import dagger.functional.multipackage.b.BModule;
-import dagger.functional.multipackage.c.CModule;
-import dagger.functional.multipackage.foo.Foo;
-import dagger.functional.multipackage.grandsub.FooGrandchildComponent;
-
-@Subcomponent(modules = {BModule.class, CModule.class})
-public interface FooChildComponent {
-  Foo<FooChildComponent> foo();
-
-  FooGrandchildComponent fooGrandchildComponent();
-}
diff --git a/javatests/dagger/functional/nullables/NullComponent.java b/javatests/dagger/functional/nullables/NullComponent.java
deleted file mode 100644
index 39f0d34..0000000
--- a/javatests/dagger/functional/nullables/NullComponent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-import dagger.Component;
-import javax.inject.Provider;
-
-@Component(modules = NullModule.class)
-interface NullComponent {
-  NullFoo nullFoo();
-  @Nullable String string();
-  Provider<String> stringProvider();
-  Number number();
-  Provider<Number> numberProvider();
-  @Nullable Integer integer();
-}
diff --git a/javatests/dagger/functional/nullables/NullComponentWithDependency.java b/javatests/dagger/functional/nullables/NullComponentWithDependency.java
deleted file mode 100644
index dfb4b82..0000000
--- a/javatests/dagger/functional/nullables/NullComponentWithDependency.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-import dagger.Component;
-import javax.inject.Provider;
-
-@Component(dependencies = NullComponent.class)
-interface NullComponentWithDependency {
-  @Nullable String string();
-  Provider<String> stringProvider();
-  Number number();
-  Provider<Number> numberProvider();
-}
diff --git a/javatests/dagger/functional/nullables/NullFoo.java b/javatests/dagger/functional/nullables/NullFoo.java
deleted file mode 100644
index b3f9a67..0000000
--- a/javatests/dagger/functional/nullables/NullFoo.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-class NullFoo {
-  final String string;
-  final Provider<String> stringProvider;
-  final Number number;
-  final Provider<Number> numberProvider;
-
-  @Inject
-  NullFoo(@Nullable String string,
-      Provider<String> stringProvider,
-      Number number,
-      Provider<Number> numberProvider) {
-    this.string = string;
-    this.stringProvider = stringProvider;
-    this.number = number;
-    this.numberProvider = numberProvider;
-  }
-
-  String methodInjectedString;
-  Provider<String> methodInjectedStringProvider;
-  Number methodInjectedNumber;
-  Provider<Number> methodInjectedNumberProvider;
-  @Inject void inject(@Nullable String string,
-      Provider<String> stringProvider,
-      Number number,
-      Provider<Number> numberProvider) {
-    this.methodInjectedString = string;
-    this.methodInjectedStringProvider = stringProvider;
-    this.methodInjectedNumber = number;
-    this.methodInjectedNumberProvider = numberProvider;
-  }
-
-  @Nullable @Inject String fieldInjectedString;
-  @Inject Provider<String> fieldInjectedStringProvider;
-  @Inject Number fieldInjectedNumber;
-  @Inject Provider<Number> fieldInjectedNumberProvider;
-}
diff --git a/javatests/dagger/functional/nullables/NullModule.java b/javatests/dagger/functional/nullables/NullModule.java
deleted file mode 100644
index 0219165..0000000
--- a/javatests/dagger/functional/nullables/NullModule.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Reusable;
-
-@Module
-class NullModule {
-  Number numberValue = null;
-  Integer integerCallCount = 0;
-
-  @Nullable
-  @Provides
-  String provideNullableString() {
-    return null;
-  }
-
-  @Provides
-  Number provideNumber() {
-    return numberValue;
-  }
-
-  @Nullable
-  @Provides
-  @Reusable
-  Integer provideNullReusableInteger() {
-    integerCallCount++;
-    return null;
-  }
-}
diff --git a/javatests/dagger/functional/nullables/NullabilityTest.java b/javatests/dagger/functional/nullables/NullabilityTest.java
deleted file mode 100644
index 6706ece..0000000
--- a/javatests/dagger/functional/nullables/NullabilityTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NullabilityTest {
-  @Test public void testNullability_provides() {
-    NullModule module = new NullModule();
-    NullComponent component = DaggerNullComponent.builder().nullModule(module).build();
-
-    // Can't construct NullFoo because it depends on Number, and Number was null.
-    try {
-      component.nullFoo();
-      fail();
-    } catch (NullPointerException npe) {
-      assertThat(npe)
-          .hasMessageThat()
-          .isEqualTo("Cannot return null from a non-@Nullable @Provides method");
-    }
-
-    // set number to non-null so we can create
-    module.numberValue = 1;
-    NullFoo nullFoo = component.nullFoo();
-
-    // Then set it back to null so we can test its providers.
-    module.numberValue = null;
-    validate(true, nullFoo.string, nullFoo.stringProvider, nullFoo.numberProvider);
-    validate(true, nullFoo.methodInjectedString, nullFoo.methodInjectedStringProvider,
-        nullFoo.methodInjectedNumberProvider);
-    validate(true, nullFoo.fieldInjectedString, nullFoo.fieldInjectedStringProvider,
-        nullFoo.fieldInjectedNumberProvider);
-  }
-
-  @Test public void testNullability_reusuable() {
-    NullModule module = new NullModule();
-    NullComponent component = DaggerNullComponent.builder().nullModule(module).build();
-
-    // Test that the @Nullable @Reusuable binding is cached properly even when the value is null.
-    assertThat(module.integerCallCount).isEqualTo(0);
-    assertThat(component.integer()).isNull();
-    assertThat(module.integerCallCount).isEqualTo(1);
-    assertThat(component.integer()).isNull();
-    assertThat(module.integerCallCount).isEqualTo(1);
-  }
-
-  @Test public void testNullability_components() {
-    NullComponent nullComponent = new NullComponent() {
-      @Override public Provider<String> stringProvider() {
-        return new Provider<String>() {
-          @Override public String get() {
-            return null;
-          }
-        };
-      }
-
-      @Override public String string() {
-        return null;
-      }
-
-      @Override public Provider<Number> numberProvider() {
-        return new Provider<Number>() {
-          @Override public Number get() {
-            return null;
-          }
-        };
-      }
-
-      @Override public Number number() {
-        return null;
-      }
-
-      @Override public NullFoo nullFoo() {
-        return null;
-      }
-
-      @Override public Integer integer() {
-        return null;
-      }
-    };
-    NullComponentWithDependency component =
-        DaggerNullComponentWithDependency.builder().nullComponent(nullComponent).build();
-    validate(false, component.string(), component.stringProvider(), component.numberProvider());
-
-    // Also validate that the component's number() method fails
-    try {
-      component.number();
-      fail();
-    } catch (NullPointerException npe) {
-      assertThat(npe)
-          .hasMessageThat()
-          .isEqualTo("Cannot return null from a non-@Nullable component method");
-    }
-  }
-
-  private void validate(boolean fromProvides,
-      String string,
-      Provider<String> stringProvider,
-      Provider<Number> numberProvider) {
-    assertThat(string).isNull();
-    assertThat(numberProvider).isNotNull();
-    try {
-      numberProvider.get();
-      fail();
-    } catch (NullPointerException npe) {
-      assertThat(npe)
-          .hasMessageThat()
-          .isEqualTo(
-              "Cannot return null from a non-@Nullable "
-                  + (fromProvides ? "@Provides" : "component")
-                  + " method");
-    }
-    assertThat(stringProvider.get()).isNull();
-  }
-}
diff --git a/javatests/dagger/functional/nullables/Nullable.java b/javatests/dagger/functional/nullables/Nullable.java
deleted file mode 100644
index cbfb98a..0000000
--- a/javatests/dagger/functional/nullables/Nullable.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.nullables;
-
-@interface Nullable {}
diff --git a/javatests/dagger/functional/producers/BUILD b/javatests/dagger/functional/producers/BUILD
deleted file mode 100644
index 36c9701..0000000
--- a/javatests/dagger/functional/producers/BUILD
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Functional tests for Dagger Producers
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-    "SOURCE_7_TARGET_7",
-)
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "producers-functional-tests",
-    srcs = glob(["**/*.java"]),
-    javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = [
-        "//:producers_with_compiler",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr305_annotations",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/mockito",
-        "@google_bazel_common//third_party/java/truth",
-        "@google_bazel_common//third_party/java/truth:truth8",
-    ],
-)
-
-test_suite(name = "AllTests")
diff --git a/javatests/dagger/functional/producers/DependedComponent.java b/javatests/dagger/functional/producers/DependedComponent.java
deleted file mode 100644
index 9a4947a..0000000
--- a/javatests/dagger/functional/producers/DependedComponent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import dagger.Component;
-
-@Component(modules = DependedModule.class)
-interface DependedComponent {
-  String getGreeting();
-}
-
diff --git a/javatests/dagger/functional/producers/DependedModule.java b/javatests/dagger/functional/producers/DependedModule.java
deleted file mode 100644
index 89ca4fc..0000000
--- a/javatests/dagger/functional/producers/DependedModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class DependedModule {
-  @Provides
-  String provideGreeting() {
-    return "Hello world!";
-  }
-}
diff --git a/javatests/dagger/functional/producers/DependedProducerModule.java b/javatests/dagger/functional/producers/DependedProducerModule.java
deleted file mode 100644
index c25d4e8..0000000
--- a/javatests/dagger/functional/producers/DependedProducerModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-@ProducerModule
-final class DependedProducerModule {
-
-  @Produces
-  int produceNumberOfGreetings() {
-    return 2;
-  }
-}
diff --git a/javatests/dagger/functional/producers/DependedProductionComponent.java b/javatests/dagger/functional/producers/DependedProductionComponent.java
deleted file mode 100644
index d5ebc4f..0000000
--- a/javatests/dagger/functional/producers/DependedProductionComponent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.ProductionComponent;
-
-@ProductionComponent(modules = {ExecutorModule.class, DependedProducerModule.class})
-interface DependedProductionComponent {
-  ListenableFuture<Integer> numGreetings();
-}
-
diff --git a/javatests/dagger/functional/producers/DependentComponent.java b/javatests/dagger/functional/producers/DependentComponent.java
deleted file mode 100644
index 364676c..0000000
--- a/javatests/dagger/functional/producers/DependentComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.ProductionComponent;
-import java.util.List;
-
-@ProductionComponent(
-  modules = {ExecutorModule.class, DependentProducerModule.class},
-  dependencies = {DependedComponent.class, DependedProductionComponent.class}
-)
-interface DependentComponent {
-  ListenableFuture<List<String>> greetings();
-}
diff --git a/javatests/dagger/functional/producers/DependentProducerModule.java b/javatests/dagger/functional/producers/DependentProducerModule.java
deleted file mode 100644
index 56b66f5..0000000
--- a/javatests/dagger/functional/producers/DependentProducerModule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.base.Ascii;
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.util.List;
-
-@ProducerModule
-final class DependentProducerModule {
-  @Produces
-  ListenableFuture<List<String>> greetings(Integer numGreetings, String greeting) {
-    List<String> greetings = ImmutableList.of(
-        String.valueOf(numGreetings), greeting, Ascii.toUpperCase(greeting));
-    return Futures.immediateFuture(greetings);
-  }
-}
diff --git a/javatests/dagger/functional/producers/DependentTest.java b/javatests/dagger/functional/producers/DependentTest.java
deleted file mode 100644
index 920d753..0000000
--- a/javatests/dagger/functional/producers/DependentTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DependentTest {
-  @Test public void dependentComponent() throws Exception {
-    DependentComponent dependentComponent =
-        DaggerDependentComponent.builder()
-            .dependedProductionComponent(DaggerDependedProductionComponent.create())
-            .dependedComponent(DaggerDependedComponent.create())
-            .build();
-    assertThat(dependentComponent).isNotNull();
-    assertThat(dependentComponent.greetings().get()).containsExactly(
-        "2", "Hello world!", "HELLO WORLD!");
-  }
-
-  @Test public void reuseBuilderWithDependentComponent() throws Exception {
-    DaggerDependentComponent.Builder dependentComponentBuilder = DaggerDependentComponent.builder();
-
-    DependentComponent componentUsingComponents =
-        dependentComponentBuilder
-            .dependedProductionComponent(DaggerDependedProductionComponent.create())
-            .dependedComponent(DaggerDependedComponent.create())
-            .build();
-
-    DependentComponent componentUsingJavaImpls = dependentComponentBuilder
-        .dependedProductionComponent(new DependedProductionComponent() {
-          @Override public ListenableFuture<Integer> numGreetings() {
-            return Futures.immediateFuture(3);
-          }
-        })
-        .dependedComponent(new DependedComponent() {
-          @Override public String getGreeting() {
-            return "Goodbye world!";
-          }
-        })
-        .build();
-
-    assertThat(componentUsingJavaImpls.greetings().get()).containsExactly(
-        "3", "Goodbye world!", "GOODBYE WORLD!");
-    assertThat(componentUsingComponents.greetings().get()).containsExactly(
-        "2", "Hello world!", "HELLO WORLD!");
-
-  }
-}
diff --git a/javatests/dagger/functional/producers/ExecutorModule.java b/javatests/dagger/functional/producers/ExecutorModule.java
deleted file mode 100644
index 5f8bfbf..0000000
--- a/javatests/dagger/functional/producers/ExecutorModule.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers;
-
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.Module;
-import dagger.Provides;
-import dagger.producers.Production;
-import java.util.concurrent.Executor;
-
-/**
- * A module that provides an optionally user-defined executor for a production component, defaulting
- * to the direct executor.
- */
-@Module
-public final class ExecutorModule {
-  private final Executor executor;
-
-  public ExecutorModule() {
-    this(MoreExecutors.directExecutor());
-  }
-
-  public ExecutorModule(Executor executor) {
-    this.executor = executor;
-  }
-
-  @Provides
-  @Production
-  Executor executor() {
-    return executor;
-  }
-}
diff --git a/javatests/dagger/functional/producers/GenericComponent.java b/javatests/dagger/functional/producers/GenericComponent.java
deleted file mode 100644
index 775ac2a..0000000
--- a/javatests/dagger/functional/producers/GenericComponent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.GenericComponent.NongenericModule;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-import java.util.Arrays;
-import java.util.List;
-
-@ProductionComponent(modules = {ExecutorModule.class, NongenericModule.class})
-interface GenericComponent {
-
-  ListenableFuture<List<String>> list(); // b/71595104
-
-  // b/71595104
-  @ProducerModule
-  abstract class GenericModule<T> {
-
-    @Produces
-    List<T> list(T t, String string) {
-      return Arrays.asList(t);
-    }
-  }
-
-  // b/71595104
-  @ProducerModule
-  class NongenericModule extends GenericModule<String> {
-    @Produces
-    static String string() {
-      return "string";
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/ProducerFactoryTest.java b/javatests/dagger/functional/producers/ProducerFactoryTest.java
deleted file mode 100644
index c85e342..0000000
--- a/javatests/dagger/functional/producers/ProducerFactoryTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.when;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import dagger.producers.Producer;
-import dagger.producers.internal.AbstractProducer;
-import dagger.producers.internal.CancellableProducer;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import javax.inject.Provider;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public class ProducerFactoryTest {
-  @Mock private ProductionComponentMonitor componentMonitor;
-  private ProducerMonitor monitor;
-  private Provider<Executor> executorProvider;
-  private Provider<ProductionComponentMonitor> componentMonitorProvider;
-
-  @Before
-  public void setUpMocks() {
-    MockitoAnnotations.initMocks(this);
-    monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS);
-    when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor);
-    // TODO(beder): Use Providers.of when available.
-    executorProvider =
-        new Provider<Executor>() {
-          @Override
-          public Executor get() {
-            return MoreExecutors.directExecutor();
-          }
-        };
-    componentMonitorProvider =
-        new Provider<ProductionComponentMonitor>() {
-          @Override
-          public ProductionComponentMonitor get() {
-            return componentMonitor;
-          }
-        };
-  }
-
-  @Test
-  public void noArgMethod() throws Exception {
-    ProducerToken token = ProducerToken.create(SimpleProducerModule_StrFactory.class);
-    Producer<String> producer =
-        SimpleProducerModule_StrFactory.create(executorProvider, componentMonitorProvider);
-    assertThat(producer.get().get()).isEqualTo("str");
-    InOrder order = inOrder(componentMonitor, monitor);
-    order.verify(componentMonitor).producerMonitorFor(token);
-    order.verify(monitor).methodStarting();
-    order.verify(monitor).methodFinished();
-    order.verify(monitor).succeeded("str");
-    order.verifyNoMoreInteractions();
-  }
-
-  @Test
-  public void singleArgMethod() throws Exception {
-    SettableFuture<Integer> intFuture = SettableFuture.create();
-    CancellableProducer<Integer> intProducer = producerOfFuture(intFuture);
-    Producer<String> producer =
-        SimpleProducerModule_StrWithArgFactory.create(
-            executorProvider, componentMonitorProvider, intProducer);
-    assertThat(producer.get().isDone()).isFalse();
-    intFuture.set(42);
-    assertThat(producer.get().get()).isEqualTo("str with arg");
-  }
-
-  @Test
-  public void successMonitor() throws Exception {
-    ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
-
-    SettableFuture<String> strFuture = SettableFuture.create();
-    @SuppressWarnings("FutureReturnValueIgnored")
-    SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
-    CancellableProducer<SettableFuture<String>> strFutureProducer =
-        producerOfFuture(strFutureFuture);
-    Producer<String> producer =
-        SimpleProducerModule_SettableFutureStrFactory.create(
-            executorProvider, componentMonitorProvider, strFutureProducer);
-    assertThat(producer.get().isDone()).isFalse();
-
-    InOrder order = inOrder(componentMonitor, monitor);
-    order.verify(componentMonitor).producerMonitorFor(token);
-
-    strFutureFuture.set(strFuture);
-    order.verify(monitor).methodStarting();
-    order.verify(monitor).methodFinished();
-    assertThat(producer.get().isDone()).isFalse();
-
-    strFuture.set("monkey");
-    assertThat(producer.get().get()).isEqualTo("monkey");
-    order.verify(monitor).succeeded("monkey");
-
-    order.verifyNoMoreInteractions();
-  }
-
-  @Test
-  public void failureMonitor() throws Exception {
-    ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
-
-    SettableFuture<String> strFuture = SettableFuture.create();
-    @SuppressWarnings("FutureReturnValueIgnored")
-    SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
-    CancellableProducer<SettableFuture<String>> strFutureProducer =
-        producerOfFuture(strFutureFuture);
-    Producer<String> producer =
-        SimpleProducerModule_SettableFutureStrFactory.create(
-            executorProvider, componentMonitorProvider, strFutureProducer);
-    assertThat(producer.get().isDone()).isFalse();
-
-    InOrder order = inOrder(componentMonitor, monitor);
-    order.verify(componentMonitor).producerMonitorFor(token);
-
-    strFutureFuture.set(strFuture);
-    order.verify(monitor).methodStarting();
-    order.verify(monitor).methodFinished();
-    assertThat(producer.get().isDone()).isFalse();
-
-    Throwable t = new RuntimeException("monkey");
-    strFuture.setException(t);
-    try {
-      producer.get().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(t);
-      order.verify(monitor).failed(t);
-    }
-
-    order.verifyNoMoreInteractions();
-  }
-
-  @Test
-  public void failureMonitorDueToThrowingProducer() throws Exception {
-    ProducerToken token = ProducerToken.create(SimpleProducerModule_ThrowingProducerFactory.class);
-
-    Producer<String> producer =
-        SimpleProducerModule_ThrowingProducerFactory.create(
-            executorProvider, componentMonitorProvider);
-    assertThat(producer.get().isDone()).isTrue();
-
-    InOrder order = inOrder(componentMonitor, monitor);
-    order.verify(componentMonitor).producerMonitorFor(token);
-
-    order.verify(monitor).methodStarting();
-    order.verify(monitor).methodFinished();
-
-    try {
-      producer.get().get();
-      fail();
-    } catch (ExecutionException e) {
-      order.verify(monitor).failed(e.getCause());
-    }
-
-    order.verifyNoMoreInteractions();
-  }
-
-  @Test(expected = NullPointerException.class)
-  public void nullComponentMonitorProvider() throws Exception {
-    SimpleProducerModule_StrFactory.create(executorProvider, null);
-  }
-
-  private static <T> CancellableProducer<T> producerOfFuture(final ListenableFuture<T> future) {
-    return new AbstractProducer<T>() {
-      @Override
-      public ListenableFuture<T> compute() {
-        return future;
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/functional/producers/ProvidesInProducerModule.java b/javatests/dagger/functional/producers/ProvidesInProducerModule.java
deleted file mode 100644
index 6e3b41f..0000000
--- a/javatests/dagger/functional/producers/ProvidesInProducerModule.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.Provides;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import java.util.concurrent.Executor;
-
-final class ProvidesInProducerModule {
-  @ProducerModule
-  static class OnlyModule {
-    @Provides
-    @Production
-    static Executor provideExecutor() {
-      return MoreExecutors.directExecutor();
-    }
-
-    @Produces
-    static String produceString() {
-      return "produced";
-    }
-  }
-
-  @ProductionComponent(modules = OnlyModule.class)
-  interface C {
-    ListenableFuture<String> string();
-  }
-}
diff --git a/javatests/dagger/functional/producers/Request.java b/javatests/dagger/functional/producers/Request.java
deleted file mode 100644
index d4020c8..0000000
--- a/javatests/dagger/functional/producers/Request.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import javax.inject.Inject;
-
-final class Request {
-  private final String name;
-
-  @Inject
-  Request() {
-    this.name = "Request";
-  }
-
-  String name() {
-    return this.name;
-  }
-}
diff --git a/javatests/dagger/functional/producers/Response.java b/javatests/dagger/functional/producers/Response.java
deleted file mode 100644
index ca5c0c2..0000000
--- a/javatests/dagger/functional/producers/Response.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-final class Response {
-  private final String data;
-
-  Response(String data) {
-    this.data = data;
-  }
-
-  String data() {
-    return this.data;
-  }
-}
diff --git a/javatests/dagger/functional/producers/ResponseModule.java b/javatests/dagger/functional/producers/ResponseModule.java
deleted file mode 100644
index 9a5e25d..0000000
--- a/javatests/dagger/functional/producers/ResponseModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class ResponseModule {
-  @Provides
-  static int requestNumber() {
-    return 5;
-  }
-}
diff --git a/javatests/dagger/functional/producers/ResponseProducerModule.java b/javatests/dagger/functional/producers/ResponseProducerModule.java
deleted file mode 100644
index 7b76ae2..0000000
--- a/javatests/dagger/functional/producers/ResponseProducerModule.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.Lazy;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-@ProducerModule(includes = ResponseModule.class)
-final class ResponseProducerModule {
-  @Qualifier
-  @interface RequestsProducerAndProduced {}
-
-  @Produces
-  static ListenableFuture<String> greeting() {
-    return Futures.immediateFuture("Hello");
-  }
-
-  @Produces
-  @RequestsProducerAndProduced
-  static ListenableFuture<String> intermediateGreeting(
-      // TODO(beder): Allow Producer and Provider of the same type (which would force the binding
-      // to be a provision binding), and add validation for that.
-      @SuppressWarnings("unused") String greeting,
-      Producer<String> greetingProducer,
-      @SuppressWarnings("unused") Produced<String> greetingProduced,
-      @SuppressWarnings("unused") Provider<Integer> requestNumberProvider,
-      @SuppressWarnings("unused") Lazy<Integer> requestNumberLazy) {
-    return greetingProducer.get();
-  }
-
-  @Produces
-  static Response response(
-      @RequestsProducerAndProduced String greeting, Request request, int requestNumber) {
-    return new Response(String.format("%s, %s #%d!", greeting, request.name(), requestNumber));
-  }
-}
diff --git a/javatests/dagger/functional/producers/SimpleComponent.java b/javatests/dagger/functional/producers/SimpleComponent.java
deleted file mode 100644
index 4b0af7f..0000000
--- a/javatests/dagger/functional/producers/SimpleComponent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.ProductionComponent;
-
-@ProductionComponent(modules = {ExecutorModule.class, ResponseProducerModule.class})
-interface SimpleComponent {
-  ListenableFuture<Response> response();
-}
diff --git a/javatests/dagger/functional/producers/SimpleProducerModule.java b/javatests/dagger/functional/producers/SimpleProducerModule.java
deleted file mode 100644
index b0c523d..0000000
--- a/javatests/dagger/functional/producers/SimpleProducerModule.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import dagger.Lazy;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.io.IOException;
-import java.util.Set;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-/**
- * A module that contains various signatures of produces methods. This is not used in any
- * components.
- */
-@ProducerModule
-final class SimpleProducerModule {
-  @Qualifier @interface Qual {
-    int value();
-  }
-
-  // Unique bindings.
-
-  @Produces
-  @Qual(-2)
-  static ListenableFuture<String> throwingProducer() {
-    throw new RuntimeException("monkey");
-  }
-
-  @Produces
-  @Qual(-1)
-  static ListenableFuture<String> settableFutureStr(SettableFuture<String> future) {
-    return future;
-  }
-
-  @Produces
-  @Qual(0)
-  static String str() {
-    return "str";
-  }
-
-  @Produces
-  @Qual(1)
-  static ListenableFuture<String> futureStr() {
-    return Futures.immediateFuture("future str");
-  }
-
-  @Produces
-  @Qual(2)
-  static String strWithArg(@SuppressWarnings("unused") int i) {
-    return "str with arg";
-  }
-
-  @Produces
-  @Qual(3)
-  static ListenableFuture<String> futureStrWithArg(@SuppressWarnings("unused") int i) {
-    return Futures.immediateFuture("future str with arg");
-  }
-
-  @Produces
-  @Qual(4)
-  @SuppressWarnings("unused") // unthrown exception for test
-  static String strThrowingException() throws IOException {
-    return "str throwing exception";
-  }
-
-  @Produces
-  @Qual(5)
-  @SuppressWarnings("unused") // unthrown exception for test
-  static ListenableFuture<String> futureStrThrowingException() throws IOException {
-    return Futures.immediateFuture("future str throwing exception");
-  }
-
-  @Produces
-  @Qual(6)
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static String strWithArgThrowingException(int i) throws IOException {
-    return "str with arg throwing exception";
-  }
-
-  @Produces
-  @Qual(7)
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static ListenableFuture<String> futureStrWithArgThrowingException(int i) throws IOException {
-    return Futures.immediateFuture("future str with arg throwing exception");
-  }
-
-  @Produces
-  @Qual(8)
-  static String strWithArgs(
-      @SuppressWarnings("unused") int i,
-      @SuppressWarnings("unused") Produced<Double> b,
-      @SuppressWarnings("unused") Producer<Object> c,
-      @SuppressWarnings("unused") Provider<Boolean> d) {
-    return "str with args";
-  }
-
-  @Produces
-  @Qual(9)
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameters for test
-  static String strWithArgsThrowingException(
-      int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) throws IOException {
-    return "str with args throwing exception";
-  }
-
-  @Produces
-  @Qual(10)
-  static ListenableFuture<String> futureStrWithArgs(
-      @SuppressWarnings("unused") int i,
-      @SuppressWarnings("unused") Produced<Double> b,
-      @SuppressWarnings("unused") Producer<Object> c,
-      @SuppressWarnings("unused") Provider<Boolean> d) {
-    return Futures.immediateFuture("future str with args");
-  }
-
-  @Produces
-  @Qual(11)
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static ListenableFuture<String> futureStrWithArgsThrowingException(
-      int i, Produced<Double> b, Producer<Object> c, Provider<Boolean> d) throws IOException {
-    return Futures.immediateFuture("str with args throwing exception");
-  }
-
-  @Produces
-  @Qual(12)
-  static String strWithFrameworkTypeArgs(
-      @SuppressWarnings("unused") @Qual(1) int i,
-      @SuppressWarnings("unused") @Qual(1) Provider<Integer> iProvider,
-      @SuppressWarnings("unused") @Qual(1) Lazy<Integer> iLazy,
-      @SuppressWarnings("unused") @Qual(2) int j,
-      @SuppressWarnings("unused") @Qual(2) Produced<Integer> jProduced,
-      @SuppressWarnings("unused") @Qual(2) Producer<Integer> jProducer,
-      @SuppressWarnings("unused") @Qual(3) Produced<Integer> kProduced,
-      @SuppressWarnings("unused") @Qual(3) Producer<Integer> kProducer) {
-    return "str with framework type args";
-  }
-
-  // Set bindings.
-
-  @Produces
-  @IntoSet
-  static String setOfStrElement() {
-    return "set of str element";
-  }
-
-  @Produces
-  @IntoSet
-  @SuppressWarnings("unused") // unthrown exception for test
-  static String setOfStrElementThrowingException() throws IOException {
-    return "set of str element throwing exception";
-  }
-
-  @Produces
-  @IntoSet
-  static ListenableFuture<String> setOfStrFutureElement() {
-    return Futures.immediateFuture("set of str element");
-  }
-
-  @Produces
-  @IntoSet
-  @SuppressWarnings("unused") // unthrown exception for test
-  static ListenableFuture<String> setOfStrFutureElementThrowingException() throws IOException {
-    return Futures.immediateFuture("set of str element throwing exception");
-  }
-
-  @Produces
-  @IntoSet
-  static String setOfStrElementWithArg(@SuppressWarnings("unused") int i) {
-    return "set of str element with arg";
-  }
-
-  @Produces
-  @IntoSet
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static String setOfStrElementWithArgThrowingException(int i) throws IOException {
-    return "set of str element with arg throwing exception";
-  }
-
-  @Produces
-  @IntoSet
-  static ListenableFuture<String> setOfStrFutureElementWithArg(@SuppressWarnings("unused") int i) {
-    return Futures.immediateFuture("set of str element with arg");
-  }
-
-  @Produces
-  @IntoSet
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static ListenableFuture<String> setOfStrFutureElementWithArgThrowingException(int i)
-      throws IOException {
-    return Futures.immediateFuture("set of str element with arg throwing exception");
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static Set<String> setOfStrValues() {
-    return ImmutableSet.of("set of str 1", "set of str 2");
-  }
-
-  @Produces
-  @ElementsIntoSet
-  @SuppressWarnings("unused") // unthrown exception for test
-  static Set<String> setOfStrValuesThrowingException() throws IOException {
-    return ImmutableSet.of("set of str 1", "set of str 2 throwing exception");
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static ListenableFuture<Set<String>> setOfStrFutureValues() {
-    return Futures.<Set<String>>immediateFuture(ImmutableSet.of("set of str 1", "set of str 2"));
-  }
-
-  @Produces
-  @ElementsIntoSet
-  @SuppressWarnings("unused") // unthrown exception for test
-  static ListenableFuture<Set<String>> setOfStrFutureValuesThrowingException() throws IOException {
-    return Futures.<Set<String>>immediateFuture(
-        ImmutableSet.of("set of str 1", "set of str 2 throwing exception"));
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static Set<String> setOfStrValuesWithArg(@SuppressWarnings("unused") int i) {
-    return ImmutableSet.of("set of str with arg 1", "set of str with arg 2");
-  }
-
-  @Produces
-  @ElementsIntoSet
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static Set<String> setOfStrValuesWithArgThrowingException(int i) throws IOException {
-    return ImmutableSet.of("set of str with arg 1", "set of str with arg 2 throwing exception");
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static ListenableFuture<Set<String>> setOfStrFutureValuesWithArg(
-      @SuppressWarnings("unused") int i) {
-    return Futures.<Set<String>>immediateFuture(
-        ImmutableSet.of("set of str with arg 1", "set of str with arg 2"));
-  }
-
-  @Produces
-  @ElementsIntoSet
-  @SuppressWarnings("unused") // unthrown exception for test, unused parameter for test
-  static ListenableFuture<Set<String>> setOfStrFutureValuesWithArgThrowingException(int i)
-      throws IOException {
-    return Futures.<Set<String>>immediateFuture(
-        ImmutableSet.of("set of str with arg 1", "set of str with arg 2 throwing exception"));
-  }
-
-  /**
-   * A binding method that might result in a generated factory with conflicting field and parameter
-   * names.
-   */
-  @Produces
-  static Object object(int foo, Provider<String> fooProvider) {
-    return foo + fooProvider.get();
-  }
-}
diff --git a/javatests/dagger/functional/producers/SimpleTest.java b/javatests/dagger/functional/producers/SimpleTest.java
deleted file mode 100644
index e20d098..0000000
--- a/javatests/dagger/functional/producers/SimpleTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SimpleTest {
-  @Test public void testSimpleComponent() throws Exception {
-    SimpleComponent simpleComponent = DaggerSimpleComponent.create();
-    assertThat(simpleComponent).isNotNull();
-    assertThat(simpleComponent.response().get().data()).isEqualTo("Hello, Request #5!");
-  }
-}
diff --git a/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java b/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java
deleted file mode 100644
index ef37df2..0000000
--- a/javatests/dagger/functional/producers/aot/ProducesMethodShadowsInjectConstructorTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2019 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.functional.producers.aot;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.BindsOptionalOf;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import javax.inject.Inject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ProducesMethodShadowsInjectConstructorTest {
-  static class Multibound {}
-  static class Maybe {}
-
-  static class HasInjectConstructor {
-    @Inject HasInjectConstructor() {}
-  }
-
-  static class DependsOnShadowingProducer {}
-
-  @ProducerModule
-  abstract static class LeafModule {
-    @Produces
-    static DependsOnShadowingProducer dependsOnShadowingProducer(
-        // When viewed just within the leaf, this will resolve HasInjectConstructor to the @Inject
-        // constructor (and will receive a producerFromProvider), but when viewed within an ancestor
-        // that defines a @Produces method for HasInjectConstructor, the binding will be a regular
-        // Producer
-        HasInjectConstructor hasInjectConstructor,
-        Optional<Maybe> maybe) {
-      return new DependsOnShadowingProducer();
-    }
-
-    @Provides
-    @IntoSet
-    static Multibound provisionContribution() {
-      return new Multibound();
-    }
-
-    @BindsOptionalOf
-    abstract Maybe maybe();
-  }
-
-  @ProductionSubcomponent(modules = LeafModule.class)
-  interface Leaf {
-    ListenableFuture<DependsOnShadowingProducer> dependsOnShadowingProducer();
-    ListenableFuture<Set<Multibound>> shadowedProvisionMultibinding();
-    ListenableFuture<Optional<Maybe>> emptyProvisionBindingToPresentProductionBinding();
-  }
-
-  @ProducerModule
-  static class RootModule {
-    @Produces
-    static HasInjectConstructor shadowInjectConstructor() {
-      return new HasInjectConstructor();
-    }
-
-    @Produces
-    @IntoSet
-    static Multibound productionContribution() {
-      return new Multibound();
-    }
-
-    @Provides
-    @Production
-    static Executor executor() {
-      return MoreExecutors.directExecutor();
-    }
-
-    @Produces
-    static Maybe presentMaybeInParent() {
-      return new Maybe();
-    }
-  }
-
-  @ProductionComponent(modules = RootModule.class)
-  interface Root {
-    Leaf leaf();
-  }
-
-  @Test
-  public void shadowedInjectConstructorDoesNotCauseClassCast() throws Exception {
-    Leaf leaf = DaggerProducesMethodShadowsInjectConstructorTest_Root.create().leaf();
-    leaf.dependsOnShadowingProducer().get();
-    assertThat(leaf.shadowedProvisionMultibinding().get()).hasSize(2);
-    assertThat(leaf.emptyProvisionBindingToPresentProductionBinding().get()).isPresent();
-  }
-}
diff --git a/javatests/dagger/functional/producers/badexecutor/BadExecutorTest.java b/javatests/dagger/functional/producers/badexecutor/BadExecutorTest.java
deleted file mode 100644
index e8fb3c5..0000000
--- a/javatests/dagger/functional/producers/badexecutor/BadExecutorTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.badexecutor;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.functional.producers.ExecutorModule;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.RejectedExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** This test verifies behavior when the executor throws {@link RejectedExecutionException}. */
-@RunWith(JUnit4.class)
-public final class BadExecutorTest {
-  private SimpleComponent component;
-
-  @Before
-  public void setUpComponent() {
-    ComponentDependency dependency =
-        new ComponentDependency() {
-          @Override
-          public ListenableFuture<Double> doubleDep() {
-            return Futures.immediateFuture(42.0);
-          }
-        };
-    ListeningExecutorService executorService = MoreExecutors.newDirectExecutorService();
-    component =
-        DaggerSimpleComponent.builder()
-            .executorModule(new ExecutorModule(executorService))
-            .componentDependency(dependency)
-            .build();
-    executorService.shutdown();
-  }
-
-  @Test
-  public void rejectNoArgMethod() throws Exception {
-    try {
-      component.noArgStr().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(RejectedExecutionException.class);
-    }
-  }
-
-  @Test
-  public void rejectSingleArgMethod() throws Exception {
-    try {
-      component.singleArgInt().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(RejectedExecutionException.class);
-    }
-  }
-
-  @Test
-  public void rejectSingleArgFromComponentDepMethod() throws Exception {
-    try {
-      component.singleArgBool().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(RejectedExecutionException.class);
-    }
-  }
-
-  @Test
-  public void doNotRejectComponentDepMethod() throws Exception {
-    assertThat(component.doubleDep().get()).isEqualTo(42.0);
-  }
-}
diff --git a/javatests/dagger/functional/producers/badexecutor/ComponentDependency.java b/javatests/dagger/functional/producers/badexecutor/ComponentDependency.java
deleted file mode 100644
index 97974e5..0000000
--- a/javatests/dagger/functional/producers/badexecutor/ComponentDependency.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.badexecutor;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-interface ComponentDependency {
-  ListenableFuture<Double> doubleDep();
-}
diff --git a/javatests/dagger/functional/producers/badexecutor/SimpleComponent.java b/javatests/dagger/functional/producers/badexecutor/SimpleComponent.java
deleted file mode 100644
index ea58125..0000000
--- a/javatests/dagger/functional/producers/badexecutor/SimpleComponent.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.badexecutor;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProductionComponent;
-
-/**
- * A component that contains entry points that exercise different execution paths, for verifying the
- * behavior when the executor throws a {@link java.util.concurrent.RejectedExecutionException}.
- */
-@ProductionComponent(
-  dependencies = ComponentDependency.class,
-  modules = {ExecutorModule.class, SimpleProducerModule.class}
-)
-interface SimpleComponent {
-  /** An entry point exposing a producer method with no args. */
-  ListenableFuture<String> noArgStr();
-
-  /** An entry point exposing a producer method that depends on another producer method. */
-  ListenableFuture<Integer> singleArgInt();
-
-  /** An entry point exposing a producer method that depends on a component dependency method. */
-  ListenableFuture<Boolean> singleArgBool();
-
-  /** An entry point exposing a component dependency method. */
-  ListenableFuture<Double> doubleDep();
-}
diff --git a/javatests/dagger/functional/producers/badexecutor/SimpleProducerModule.java b/javatests/dagger/functional/producers/badexecutor/SimpleProducerModule.java
deleted file mode 100644
index f907fda..0000000
--- a/javatests/dagger/functional/producers/badexecutor/SimpleProducerModule.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.badexecutor;
-
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-@ProducerModule
-final class SimpleProducerModule {
-  @Produces
-  static String noArgStr() {
-    return "no arg string";
-  }
-
-  @Produces
-  static int singleArgInt(String arg) {
-    return arg.length();
-  }
-
-  @Produces
-  static boolean singleArgBool(double arg) {
-    return arg > 0.0;
-  }
-}
diff --git a/javatests/dagger/functional/producers/binds/BindsProducersTest.java b/javatests/dagger/functional/producers/binds/BindsProducersTest.java
deleted file mode 100644
index 0949f02..0000000
--- a/javatests/dagger/functional/producers/binds/BindsProducersTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.binds;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class BindsProducersTest {
-
-  private SimpleBindsProductionComponent component;
-
-  @Before
-  public void setUp() {
-    component = DaggerSimpleBindsProductionComponent.create();
-  }
-
-  @Test
-  public void bindDelegates() throws Exception {
-    assertThat(component.object().get()).isInstanceOf(FooOfStrings.class);
-    assertThat(component.fooOfStrings().get()).isInstanceOf(FooOfStrings.class);
-    assertThat(component.fooOfIntegers().get()).isNotNull();
-  }
-
-  @Test
-  public void bindWithScope() throws Exception {
-    assertThat(component.qualifiedFooOfStrings().get())
-        .isSameInstanceAs(component.qualifiedFooOfStrings().get());
-  }
-
-  @Test
-  public void multibindings() throws Exception {
-    assertThat(component.foosOfNumbers().get()).hasSize(2);
-    assertThat(component.objects().get()).hasSize(3);
-    assertThat(component.charSequences().get()).hasSize(5);
-
-    assertThat(component.integerObjectMap().get())
-        .containsExactly(
-            123, "123-string", 456, "456-string", 789, "789-string", -1, "provision-string");
-
-    Map<Integer, Producer<Object>> integerProducerOfObjectMap =
-        component.integerProducerOfObjectMap().get();
-    assertThat(integerProducerOfObjectMap).hasSize(4);
-    assertThat(integerProducerOfObjectMap.get(123).get().get()).isEqualTo("123-string");
-    assertThat(integerProducerOfObjectMap.get(456).get().get()).isEqualTo("456-string");
-    assertThat(integerProducerOfObjectMap.get(789).get().get()).isEqualTo("789-string");
-    assertThat(integerProducerOfObjectMap.get(-1).get().get()).isEqualTo("provision-string");
-
-    assertThat(component.integerProducedOfObjectMap().get())
-        .containsExactly(
-            123, Produced.successful("123-string"),
-            456, Produced.successful("456-string"),
-            789, Produced.successful("789-string"),
-            -1, Produced.successful("provision-string"));
-
-    assertThat(component.qualifiedIntegerObjectMap().get()).hasSize(1);
-  }
-}
diff --git a/javatests/dagger/functional/producers/binds/Foo.java b/javatests/dagger/functional/producers/binds/Foo.java
deleted file mode 100644
index 4eb71fd..0000000
--- a/javatests/dagger/functional/producers/binds/Foo.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.binds;
-
-/**
- * This is the type that will be bound.  We throw in generics just to complicate the test.
- */
-interface Foo<T> {}
diff --git a/javatests/dagger/functional/producers/binds/FooOfStrings.java b/javatests/dagger/functional/producers/binds/FooOfStrings.java
deleted file mode 100644
index b94d907..0000000
--- a/javatests/dagger/functional/producers/binds/FooOfStrings.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.binds;
-
-/**
- * This is not marked with {@link javax.inject.Inject @Inject} in order to test that {@link
- * dagger.Binds @Binds} properly translate to {@code dagger.internal.codegen.ProductionBinding}s
- * when the right-hand-side of the method is also a production binding. We force this by adding a
- * {@link dagger.producers.Produces @Produces} method to add it to the graph instead of relying on
- * the {@code dagger.internal.codegen.ProvisionBinding} that would be created by default with an
- * {@code @Inject} constructor.
- */
-final class FooOfStrings implements Foo<String> {}
diff --git a/javatests/dagger/functional/producers/binds/SimpleBindingModule.java b/javatests/dagger/functional/producers/binds/SimpleBindingModule.java
deleted file mode 100644
index f2af277..0000000
--- a/javatests/dagger/functional/producers/binds/SimpleBindingModule.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.binds;
-
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.Executor;
-import javax.inject.Named;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-
-@ProducerModule(includes = {
-    SimpleBindingModule.ExecutorModule.class,
-    SimpleBindingModule.ProvisionModuleForMap.class
-})
-abstract class SimpleBindingModule {
-  @Binds
-  abstract Object bindObject(FooOfStrings impl);
-
-  @Binds
-  abstract Foo<String> bindFooOfStrings(FooOfStrings impl);
-
-  @Binds
-  abstract Foo<? extends Number> bindFooOfNumbers(Foo<Integer> fooOfIntegers);
-
-  @Binds
-  @Singleton
-  @SomeQualifier
-  abstract Foo<String> bindQualifiedFooOfStrings(FooOfStrings impl);
-
-  @Produces
-  static FooOfStrings produceFooOfStrings() {
-    return new FooOfStrings();
-  }
-
-  @Produces
-  static Foo<Integer> produceFooOfIntegers() {
-    return new Foo<Integer>() {};
-  }
-
-  @Produces
-  static Foo<Double> produceFooOfDoubles() {
-    return new Foo<Double>() {};
-  }
-
-  @Binds
-  @IntoSet
-  abstract Foo<? extends Number> bindFooOfIntegersIntoSet(Foo<Integer> fooOfIntegers);
-
-  @Binds
-  @IntoSet
-  abstract Foo<? extends Number> bindFooExtendsNumberIntoSet(Foo<Double> fooOfDoubles);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<Object> bindSetOfFooNumbersToObjects(Set<Foo<? extends Number>> setOfFooNumbers);
-
-  @Binds
-  @IntoSet
-  abstract Object bindFooOfStringsIntoSetOfObjects(FooOfStrings impl);
-
-  @Produces
-  static HashSet<String> produceStringHashSet() {
-    return new HashSet<>(Arrays.asList("hash-string1", "hash-string2"));
-  }
-
-  @Produces
-  static TreeSet<CharSequence> produceCharSequenceTreeSet() {
-    return new TreeSet<CharSequence>(Arrays.asList("tree-charSequence1", "tree-charSequence2"));
-  }
-
-  @Produces
-  static Collection<CharSequence> produceCharSequenceCollection() {
-    return Arrays.<CharSequence>asList("list-charSequence");
-  }
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindHashSetOfStrings(HashSet<String> set);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindTreeSetOfCharSequences(TreeSet<CharSequence> set);
-
-  @Binds
-  @ElementsIntoSet
-  abstract Set<CharSequence> bindCollectionOfCharSequences(Collection<CharSequence> collection);
-
-  @Qualifier
-  @Retention(RetentionPolicy.RUNTIME)
-  @interface SomeQualifier {}
-
-  @Module
-  static final class ExecutorModule {
-    @Provides @Production
-    static Executor provideExecutor() {
-      return MoreExecutors.directExecutor();
-    }
-  }
-
-  @Binds
-  @IntoMap
-  @IntKey(123)
-  abstract Object bind123ForMap(@Named("For-123") String string);
-
-  @Binds
-  @IntoMap
-  @IntKey(456)
-  abstract Object bind456ForMap(@Named("For-456") String string);
-
-  @Produces
-  @IntoMap
-  @IntKey(789)
-  static Object produce789ForMap() {
-    return "789-string";
-  }
-
-  @Module
-  abstract static class ProvisionModuleForMap {
-    @Provides @Named("Provision string") static String provideProvisionString() {
-      return "provision-string";
-    }
-
-    @Binds
-    @IntoMap
-    @IntKey(-1)
-    abstract Object bindNegative1ForMap(@Named("Provision string") String string);
-  }
-
-  @Binds
-  @IntoMap
-  @IntKey(123)
-  @SomeQualifier
-  abstract Object bindFooOfStringsIntoQualifiedMap(FooOfStrings fooOfStrings);
-
-  @Produces
-  @Named("For-123")
-  static String produce123String() {
-    return "123-string";
-  }
-
-  @Produces
-  @Named("For-456")
-  static String produce456String() {
-    return "456-string";
-  }
-}
diff --git a/javatests/dagger/functional/producers/binds/SimpleBindsProductionComponent.java b/javatests/dagger/functional/producers/binds/SimpleBindsProductionComponent.java
deleted file mode 100644
index 21cf661..0000000
--- a/javatests/dagger/functional/producers/binds/SimpleBindsProductionComponent.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.binds;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.binds.SimpleBindingModule.SomeQualifier;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.ProductionComponent;
-import java.util.Map;
-import java.util.Set;
-import javax.inject.Singleton;
-
-@Singleton
-@ProductionComponent(modules = SimpleBindingModule.class)
-public interface SimpleBindsProductionComponent {
-  ListenableFuture<Object> object();
-
-  ListenableFuture<Foo<String>> fooOfStrings();
-
-  @SomeQualifier
-  ListenableFuture<Foo<String>> qualifiedFooOfStrings();
-
-  ListenableFuture<Foo<Integer>> fooOfIntegers();
-
-  ListenableFuture<Set<Foo<? extends Number>>> foosOfNumbers();
-
-  ListenableFuture<Set<Object>> objects();
-
-  ListenableFuture<Set<CharSequence>> charSequences();
-
-  ListenableFuture<Map<Integer, Object>> integerObjectMap();
-
-  ListenableFuture<Map<Integer, Producer<Object>>> integerProducerOfObjectMap();
-
-  ListenableFuture<Map<Integer, Produced<Object>>> integerProducedOfObjectMap();
-
-  @SomeQualifier ListenableFuture<Map<Integer, Object>> qualifiedIntegerObjectMap();
-}
diff --git a/javatests/dagger/functional/producers/builder/DepComponent.java b/javatests/dagger/functional/producers/builder/DepComponent.java
deleted file mode 100644
index c2811f1..0000000
--- a/javatests/dagger/functional/producers/builder/DepComponent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.builder;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-interface DepComponent {
-  ListenableFuture<Double> d();
-}
diff --git a/javatests/dagger/functional/producers/builder/IntModule.java b/javatests/dagger/functional/producers/builder/IntModule.java
deleted file mode 100644
index ed2bb95..0000000
--- a/javatests/dagger/functional/producers/builder/IntModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.builder;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class IntModule {
-  @Provides
-  static int i() {
-    return 42;
-  }
-}
diff --git a/javatests/dagger/functional/producers/builder/ProductionComponentBuilderTest.java b/javatests/dagger/functional/producers/builder/ProductionComponentBuilderTest.java
deleted file mode 100644
index 14f153e..0000000
--- a/javatests/dagger/functional/producers/builder/ProductionComponentBuilderTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.builder;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link dagger.producers.ProductionComponent.Builder}. */
-@RunWith(JUnit4.class)
-public final class ProductionComponentBuilderTest {
-
-  @Test
-  public void successfulBuild() throws Exception {
-    TestComponentWithBuilder component =
-        DaggerTestComponentWithBuilder.builder()
-            .depComponent(depComponent(15.3))
-            .strModule(new StringModule())
-            .build();
-    assertThat(component.s().get()).isEqualTo("arg: 42");
-    assertThat(component.d().get()).isEqualTo(15.3);
-  }
-
-  @Test
-  public void successfulBuild_withMissingZeroArgModule() throws Exception {
-    TestComponentWithBuilder component =
-        DaggerTestComponentWithBuilder.builder()
-            .depComponent(depComponent(15.3))
-            .build();
-    assertThat(component.s().get()).isEqualTo("arg: 42");
-    assertThat(component.d().get()).isEqualTo(15.3);
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void missingDepComponent() {
-    DaggerTestComponentWithBuilder.builder()
-        .strModule(new StringModule())
-        .build();
-  }
-
-  private static DepComponent depComponent(final double value) {
-    return new DepComponent() {
-      @Override
-      public ListenableFuture<Double> d() {
-        return Futures.immediateFuture(value);
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/functional/producers/builder/StringModule.java b/javatests/dagger/functional/producers/builder/StringModule.java
deleted file mode 100644
index 6ad748f..0000000
--- a/javatests/dagger/functional/producers/builder/StringModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.builder;
-
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-@ProducerModule
-final class StringModule {
-  @Produces
-  static String str(int i) {
-    return "arg: " + i;
-  }
-}
diff --git a/javatests/dagger/functional/producers/builder/TestComponentWithBuilder.java b/javatests/dagger/functional/producers/builder/TestComponentWithBuilder.java
deleted file mode 100644
index 91fb326..0000000
--- a/javatests/dagger/functional/producers/builder/TestComponentWithBuilder.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.builder;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProductionComponent;
-
-@ProductionComponent(
-  modules = {ExecutorModule.class, StringModule.class, IntModule.class},
-  dependencies = DepComponent.class
-)
-interface TestComponentWithBuilder {
-  ListenableFuture<String> s();
-  ListenableFuture<Double> d();
-
-  @ProductionComponent.Builder
-  interface Builder {
-    Builder depComponent(DepComponent depComponent);
-    Builder strModule(StringModule strModule);
-    TestComponentWithBuilder build();
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/CancellationComponent.java b/javatests/dagger/functional/producers/cancellation/CancellationComponent.java
deleted file mode 100644
index f06829e..0000000
--- a/javatests/dagger/functional/producers/cancellation/CancellationComponent.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.BindsInstance;
-import dagger.functional.producers.cancellation.CancellationComponent.Dependency;
-import dagger.producers.Producer;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import java.util.concurrent.Executor;
-import javax.inject.Named;
-
-@ProductionComponent(modules = CancellationModule.class, dependencies = Dependency.class)
-interface CancellationComponent {
-
-  @Named("ep1")
-  ListenableFuture<String> entryPoint1();
-
-  @Named("ep2")
-  Producer<String> entryPoint2();
-
-  @Named("ep3")
-  ListenableFuture<String> entryPoint3();
-
-  CancellationSubcomponent.Builder subcomponentBuilder();
-
-  @ProductionComponent.Builder
-  interface Builder {
-    Builder module(CancellationModule module);
-
-    Builder dependency(Dependency dependency);
-
-    @BindsInstance
-    Builder executor(@Production Executor executor);
-
-    CancellationComponent build();
-  }
-
-  final class Dependency {
-
-    final ProducerTester tester;
-
-    Dependency(ProducerTester tester) {
-      this.tester = checkNotNull(tester);
-    }
-
-    @SuppressWarnings("unused") // Dagger uses it
-    ListenableFuture<String> getDependencyFuture() {
-      return tester.start("dependencyFuture");
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/CancellationModule.java b/javatests/dagger/functional/producers/cancellation/CancellationModule.java
deleted file mode 100644
index ff7ee79..0000000
--- a/javatests/dagger/functional/producers/cancellation/CancellationModule.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.Provides;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import javax.inject.Named;
-
-@SuppressWarnings("unused") // not actually using dependencies
-@ProducerModule(subcomponents = CancellationSubcomponent.class)
-final class CancellationModule {
-
-  private final ProducerTester tester;
-
-  CancellationModule(ProducerTester tester) {
-    this.tester = checkNotNull(tester);
-  }
-
-  @Produces
-  @Named("leaf1")
-  ListenableFuture<String> produceLeaf1() {
-    return tester.start("leaf1");
-  }
-
-  @Produces
-  @Named("leaf2")
-  ListenableFuture<String> produceLeaf2() {
-    return tester.start("leaf2");
-  }
-
-  @Produces
-  @Named("leaf3")
-  ListenableFuture<String> produceLeaf3() {
-    return tester.start("leaf3");
-  }
-
-  @Produces
-  @Named("foo")
-  ListenableFuture<String> produceFoo(@Named("leaf1") String leaf1, @Named("leaf2") String leaf2) {
-    return tester.start("foo");
-  }
-
-  @Produces
-  @Named("bar")
-  ListenableFuture<String> produceBar(@Named("leaf2") String leaf2, @Named("leaf3") String leaf3) {
-    return tester.start("bar");
-  }
-
-  @Produces
-  @Named("baz")
-  ListenableFuture<String> produceBaz(
-      @Named("foo") Producer<String> foo, @Named("bar") String bar) {
-    ListenableFuture<String> fooFuture = foo.get();
-    if (!fooFuture.isDone()) {
-      assertThat(fooFuture.cancel(true)).isTrue();
-      assertThat(fooFuture.isCancelled()).isTrue();
-    }
-    return tester.start("baz");
-  }
-
-  @Provides
-  @Named("providesDep")
-  static String provideProvidesDep() {
-    return "providesDep";
-  }
-
-  @Produces
-  @Named("qux")
-  ListenableFuture<String> produceQux(
-      @Named("baz") String baz, @Named("providesDep") String providesDep) {
-    return tester.start("qux");
-  }
-
-  @Produces
-  @Named("ep1")
-  ListenableFuture<String> produceEntryPoint1(@Named("qux") String qux) {
-    return tester.start("entryPoint1");
-  }
-
-  @Produces
-  @Named("ep2")
-  ListenableFuture<String> produceEntryPoint2(@Named("bar") String bar, String dependency) {
-    return tester.start("entryPoint2");
-  }
-
-  @Produces
-  @Named("ep3")
-  static ListenableFuture<String> produceEntryPoint3(Producer<String> dependencyProducer) {
-    ListenableFuture<String> dependencyFuture = dependencyProducer.get();
-    assertThat(dependencyFuture.isDone()).isFalse();
-    assertThat(dependencyFuture.cancel(true)).isTrue();
-    assertThat(dependencyFuture.isCancelled()).isTrue();
-    return dependencyFuture;
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/CancellationPolicyTest.java b/javatests/dagger/functional/producers/cancellation/CancellationPolicyTest.java
deleted file mode 100644
index 936072a..0000000
--- a/javatests/dagger/functional/producers/cancellation/CancellationPolicyTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.BindsInstance;
-import dagger.producers.CancellationPolicy;
-import dagger.producers.CancellationPolicy.Propagation;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.util.concurrent.Executor;
-import javax.inject.Named;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for parent production components with a {@code CancellationPolicy} that allows subcomponent
- * cancellation to propagate to them
- */
-@RunWith(JUnit4.class)
-public final class CancellationPolicyTest {
-
-  @ProducerModule(subcomponents = Child.class)
-  static class ParentModule {
-    private final ProducerTester tester;
-
-    ParentModule(ProducerTester tester) {
-      this.tester = tester;
-    }
-
-    @Produces
-    @Named("a")
-    ListenableFuture<String> produceA() {
-      return tester.start("a");
-    }
-  }
-
-  interface Parent {
-    @Named("a")
-    ListenableFuture<String> a();
-
-    Child.Builder childBuilder();
-
-    interface Builder<P extends Parent, B extends Builder<P, B>> {
-      B module(ParentModule module);
-
-      @BindsInstance
-      B executor(@Production Executor executor);
-
-      P build();
-    }
-  }
-
-  @CancellationPolicy(fromSubcomponents = Propagation.PROPAGATE)
-  @ProductionComponent(modules = ParentModule.class)
-  interface PropagatingParent extends Parent {
-    @ProductionComponent.Builder
-    interface Builder extends Parent.Builder<PropagatingParent, Builder> {}
-  }
-
-  @CancellationPolicy(fromSubcomponents = Propagation.IGNORE)
-  @ProductionComponent(modules = ParentModule.class)
-  interface NonPropagatingParent extends Parent {
-    @ProductionComponent.Builder
-    interface Builder extends Parent.Builder<NonPropagatingParent, Builder> {}
-  }
-
-  @ProducerModule
-  static class ChildModule {
-    private final ProducerTester tester;
-
-    ChildModule(ProducerTester tester) {
-      this.tester = tester;
-    }
-
-    @Produces
-    @Named("b")
-    ListenableFuture<String> b(@Named("a") String a) {
-      return tester.start("b");
-    }
-  }
-
-  @ProductionSubcomponent(modules = ChildModule.class)
-  interface Child {
-    @Named("b")
-    ListenableFuture<String> b();
-
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      Builder module(ChildModule module);
-
-      Child build();
-    }
-  }
-
-  private final ProducerTester tester = new ProducerTester();
-
-  @Test
-  public void propagatingParent_childCancellationPropagatesToParent() {
-    PropagatingParent parent =
-        DaggerCancellationPolicyTest_PropagatingParent.builder()
-            .module(new ParentModule(tester))
-            .executor(MoreExecutors.directExecutor())
-            .build();
-    ListenableFuture<String> a = parent.a();
-
-    Child child = parent.childBuilder().module(new ChildModule(tester)).build();
-
-    ListenableFuture<String> b = child.b();
-
-    tester.assertStarted("a").only();
-
-    assertThat(a.isDone()).isFalse();
-    assertThat(b.isDone()).isFalse();
-
-    assertThat(b.cancel(true)).isTrue();
-    assertThat(b.isCancelled()).isTrue();
-
-    tester.assertCancelled("a");
-
-    assertThat(a.isCancelled()).isTrue();
-  }
-
-  @Test
-  public void nonPropagatingParent_childCancellationDoesNotPropagateToParent() throws Exception {
-    // This test is basically just checking that when the parent has fromSubcomponents = IGNORE, it
-    // behaves the same as having no @CancellationPolicy at all (as tested in
-    // ProducerSubcomponentCancellationTester)
-    NonPropagatingParent parent =
-        DaggerCancellationPolicyTest_NonPropagatingParent.builder()
-            .module(new ParentModule(tester))
-            .executor(MoreExecutors.directExecutor())
-            .build();
-    ListenableFuture<String> a = parent.a();
-
-    Child child = parent.childBuilder().module(new ChildModule(tester)).build();
-
-    ListenableFuture<String> b = child.b();
-
-    tester.assertStarted("a").only();
-
-    assertThat(a.isDone()).isFalse();
-    assertThat(b.isDone()).isFalse();
-
-    assertThat(b.cancel(true)).isTrue();
-    assertThat(b.isCancelled()).isTrue();
-
-    tester.assertNotCancelled("a");
-
-    assertThat(a.isDone()).isFalse();
-
-    tester.complete("a");
-    assertThat(a.isDone()).isTrue();
-    assertThat(a.get(1, MILLISECONDS)).isEqualTo("completed");
-
-    tester.assertNotStarted("b");
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/CancellationSubcomponent.java b/javatests/dagger/functional/producers/cancellation/CancellationSubcomponent.java
deleted file mode 100644
index 63b1a9d..0000000
--- a/javatests/dagger/functional/producers/cancellation/CancellationSubcomponent.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.ProductionSubcomponent;
-import javax.inject.Named;
-
-@ProductionSubcomponent(modules = CancellationSubcomponentModule.class)
-interface CancellationSubcomponent {
-
-  @Named("subEntryPoint")
-  ListenableFuture<String> subcomponentEntryPoint();
-
-  @ProductionSubcomponent.Builder
-  interface Builder {
-    Builder module(CancellationSubcomponentModule module);
-
-    CancellationSubcomponent build();
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/CancellationSubcomponentModule.java b/javatests/dagger/functional/producers/cancellation/CancellationSubcomponentModule.java
deleted file mode 100644
index 9cedad4..0000000
--- a/javatests/dagger/functional/producers/cancellation/CancellationSubcomponentModule.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import javax.inject.Named;
-
-@SuppressWarnings("unused") // not actually using dependencies
-@ProducerModule
-final class CancellationSubcomponentModule {
-
-  private final ProducerTester tester;
-
-  CancellationSubcomponentModule(ProducerTester tester) {
-    this.tester = checkNotNull(tester);
-  }
-
-  @Produces
-  @Named("subLeaf")
-  ListenableFuture<String> produceSubLeaf() {
-    return tester.start("subLeaf");
-  }
-
-  @Produces
-  @Named("subTask1")
-  ListenableFuture<String> produceSubTask1(
-      @Named("subLeaf") String subLeaf, @Named("qux") String qux) {
-    return tester.start("subTask1");
-  }
-
-  @Produces
-  @Named("subTask2")
-  ListenableFuture<String> produceSubTask2(@Named("foo") String foo, Producer<String> dependency) {
-    ListenableFuture<String> dependencyFuture = dependency.get();
-    assertThat(dependencyFuture.cancel(true)).isTrue();
-    assertThat(dependencyFuture.isCancelled()).isTrue();
-    return tester.start("subTask2");
-  }
-
-  @Produces
-  @Named("subEntryPoint")
-  ListenableFuture<String> produceSubEntryPoint(
-      @Named("subTask1") String subTask1, @Named("subTask2") String subTask2) {
-    return tester.start("subEntryPoint");
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/ProducerCancellationTest.java b/javatests/dagger/functional/producers/cancellation/ProducerCancellationTest.java
deleted file mode 100644
index 23b31d2..0000000
--- a/javatests/dagger/functional/producers/cancellation/ProducerCancellationTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.functional.producers.cancellation.CancellationComponent.Dependency;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests cancellation of tasks in production components. */
-@RunWith(JUnit4.class)
-public class ProducerCancellationTest {
-
-  private final ProducerTester tester = new ProducerTester();
-  private final CancellationComponent component =
-      DaggerCancellationComponent.builder()
-          .module(new CancellationModule(tester))
-          .dependency(new Dependency(tester))
-          .executor(MoreExecutors.directExecutor())
-          .build();
-
-  @Test
-  public void initialState() {
-    tester.assertNoStartedNodes();
-  }
-
-  @Test
-  public void cancellingOneEntryPoint_cancelsAllRunningNodes() {
-    ListenableFuture<String> entryPoint1 = component.entryPoint1();
-    tester.assertStarted("leaf2", "leaf3").only();
-
-    assertThat(entryPoint1.cancel(true)).isTrue();
-    assertThat(entryPoint1.isCancelled()).isTrue();
-
-    tester.assertCancelled("leaf2", "leaf3").only();
-
-    // The other entry points were also cancelled in the process, from the user's perspective.
-    assertThat(component.entryPoint2().get().isCancelled()).isTrue();
-    assertThat(component.entryPoint3().isCancelled()).isTrue();
-
-    // The underlying tasks weren't actually started, even though we just requested them above,
-    // because the node was cancelled already along with the component.
-    tester.assertNotStarted("entryPoint2", "entryPoint3");
-  }
-
-  @SuppressWarnings({"CheckReturnValue", "FutureReturnValueIgnored"})
-  @Test
-  public void cancellingNonEntryPointProducer_doesNotCancelUnderlyingTask() {
-    ListenableFuture<String> entryPoint1 = component.entryPoint1();
-    tester.assertStarted("leaf2", "leaf3").only();
-
-    tester.complete("leaf2", "leaf3");
-
-    tester.assertStarted("bar");
-
-    // foo's dependencies are complete, but it is not yet started because baz depends on
-    // Producer<foo>, so it won't be started until baz calls get() on it.
-    // baz not started yet because it needs bar to complete first.
-    tester.assertNotStarted("foo", "baz");
-
-    // Complete bar, triggering baz to run. It calls get() on the foo Producer, so that also starts
-    // once its dependency leaf1 is complete.
-    tester.complete("bar", "leaf1");
-    tester.assertStarted("baz", "foo");
-
-    // baz then cancelled the foo Producer's future, but that didn't cancel the underlying task.
-    tester.assertNotCancelled("foo");
-
-    // If we cancel the entry point, that does cancel the task.
-    entryPoint1.cancel(true);
-    tester.assertCancelled("foo");
-  }
-
-  @SuppressWarnings({"CheckReturnValue", "FutureReturnValueIgnored"})
-  @Test
-  public void cancellingProducerFromComponentDependency_cancelsUnderlyingTask() {
-    // Start leaf2/leaf3 tasks.
-    component.entryPoint1();
-    tester.assertStarted("leaf2", "leaf3").only();
-    tester.assertNotCancelled("leaf2", "leaf3");
-
-    // Nothing's requested dependencyFuture yet.
-    tester.assertNotStarted("dependencyFuture");
-
-    // entryPoint3 injects Producer of dependency future, then cancels that future. Then also
-    // returns that future as the entry point.
-    ListenableFuture<String> entryPoint = component.entryPoint3();
-
-    tester.assertStarted("dependencyFuture");
-    tester.assertCancelled("dependencyFuture");
-
-    // Even though the entry point future returned from the component is not the dependency future
-    // itself, the cancellation should have propagated out to it and cancelled it.
-    assertThat(entryPoint.isCancelled()).isTrue();
-
-    // And that cancellation should have cancelled the other tasks running in the component.
-    tester.assertCancelled("leaf2", "leaf3");
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/ProducerSubcomponentCancellationTest.java b/javatests/dagger/functional/producers/cancellation/ProducerSubcomponentCancellationTest.java
deleted file mode 100644
index 246bf9f..0000000
--- a/javatests/dagger/functional/producers/cancellation/ProducerSubcomponentCancellationTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import dagger.functional.producers.cancellation.CancellationComponent.Dependency;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests cancellation of tasks in production subcomponents. */
-@RunWith(JUnit4.class)
-public class ProducerSubcomponentCancellationTest {
-
-  private final ProducerTester tester = new ProducerTester();
-  private final CancellationComponent component =
-      DaggerCancellationComponent.builder()
-          .module(new CancellationModule(tester))
-          .dependency(new Dependency(tester))
-          .executor(MoreExecutors.directExecutor())
-          .build();
-  private final CancellationSubcomponent subcomponent =
-      component.subcomponentBuilder().module(new CancellationSubcomponentModule(tester)).build();
-
-  @Test
-  public void initialState() {
-    tester.assertNoStartedNodes();
-  }
-
-  @Test
-  public void cancellingSubcomponent_doesNotCancelParent() throws Exception {
-    ListenableFuture<String> subcomponentEntryPoint = subcomponent.subcomponentEntryPoint();
-
-    // Subcomponent entry point depends on all leaves from the parent component and on the single
-    // leaf in the subcomponent itself, so they should all have started.
-    tester.assertStarted("leaf1", "leaf2", "leaf3", "subLeaf").only();
-
-    assertThat(subcomponentEntryPoint.cancel(true)).isTrue();
-    assertThat(subcomponentEntryPoint.isCancelled()).isTrue();
-
-    // None of the tasks running in the parent were cancelled.
-    tester.assertNotCancelled("leaf1", "leaf2", "leaf3");
-    tester.assertCancelled("subLeaf").only();
-
-    // Finish all the parent tasks to ensure that it can still complete normally.
-    tester.complete(
-        "dependencyFuture",
-        "leaf1",
-        "leaf2",
-        "leaf3",
-        "foo",
-        "bar",
-        "baz",
-        "qux",
-        "entryPoint1",
-        "entryPoint2");
-
-    assertThat(component.entryPoint1().get(1, MILLISECONDS)).isEqualTo("completed");
-    assertThat(component.entryPoint2().get().get(1, MILLISECONDS)).isEqualTo("completed");
-  }
-
-  @Test
-  public void cancellingSubcomponent_preventsUnstartedNodesFromStarting() {
-    ListenableFuture<String> subcomponentEntryPoint = subcomponent.subcomponentEntryPoint();
-
-    tester.complete("subLeaf");
-    tester.assertNotStarted("subTask1", "subTask2");
-
-    subcomponentEntryPoint.cancel(true);
-
-    // Complete the remaining dependencies of subTask1 and subTask2.
-    tester.complete("leaf1", "leaf2", "leaf3", "foo", "bar", "baz", "qux");
-
-    // Since the subcomponent was cancelled, they are not started.
-    tester.assertNotStarted("subTask1", "subTask2");
-  }
-
-  @Test
-  public void cancellingProducerFromComponentDependency_inSubcomponent_cancelsUnderlyingTask()
-      throws Exception {
-    // Request subcomponent's entry point.
-    ListenableFuture<String> subcomponentEntryPoint = subcomponent.subcomponentEntryPoint();
-
-    // Finish all parent tasks so that the subcomponent's tasks can start.
-    tester.complete("leaf1", "leaf2", "leaf3", "foo", "bar", "baz", "qux", "subLeaf");
-
-    tester.assertStarted("subTask1", "subTask2");
-    tester.assertNotCancelled("subTask1", "subTask2");
-
-    // When subTask2 runs, it cancels the dependency future.
-    // TODO(cgdecker): Is this what we want to happen?
-    // On the one hand, there's a policy of "futures from component dependencies come from outside
-    // our control and should be cancelled unconditionally". On the other hand, the dependency is
-    // coming from the parent component, and the policy is also not to cancel things belonging to
-    // the parent unless it allows that.
-    tester.assertCancelled("dependencyFuture");
-
-    // The future it returns didn't depend directly on that future, though, so the subcomponent
-    // should be able to complete normally.
-    tester.complete("subTask1", "subTask2", "subEntryPoint");
-
-    assertThat(subcomponentEntryPoint.get(1, MILLISECONDS)).isEqualTo("completed");
-  }
-}
diff --git a/javatests/dagger/functional/producers/cancellation/ProducerTester.java b/javatests/dagger/functional/producers/cancellation/ProducerTester.java
deleted file mode 100644
index 35cf8e9..0000000
--- a/javatests/dagger/functional/producers/cancellation/ProducerTester.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.producers.cancellation;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Predicate;
-
-/**
- * Helper for testing producers.
- *
- * <p>Maintains a set of nodes (futures mapped to names) representing the results of different
- * producer nodes and allows those nodes to be "started" (when returned from a producer method),
- * completed, and cancelled, as well as to be queried for their state. Additionally, provides
- * assertions about the state of nodes.
- */
-final class ProducerTester {
-
-  private final Map<String, TestFuture> futures = new HashMap<>();
-
-  /** Starts the given node. */
-  ListenableFuture<String> start(String node) {
-    return getOrCreate(node).start();
-  }
-
-  private TestFuture getOrCreate(String node) {
-    TestFuture result = futures.get(node);
-    if (result == null) {
-      result = new TestFuture(node);
-      futures.put(node, result);
-    }
-    return result;
-  }
-
-  /** Returns whether or not the given node has been started. */
-  boolean isStarted(String node) {
-    return futures.containsKey(node) && futures.get(node).isStarted();
-  }
-
-  /** Completes of the given nodes. */
-  void complete(String... nodes) {
-    for (String node : nodes) {
-      getOrCreate(node).complete();
-    }
-  }
-
-  /** Returns whether or not the given node has been cancelled. */
-  boolean isCancelled(String node) {
-    TestFuture future = futures.get(node);
-    return future != null && future.isCancelled();
-  }
-
-  /** Asserts that the given nodes have been started. */
-  Only assertStarted(String... nodes) {
-    return assertAboutNodes(STARTED, nodes);
-  }
-
-  /** Asserts that the given nodes have been cancelled. */
-  Only assertCancelled(String... nodes) {
-    return assertAboutNodes(CANCELLED, nodes);
-  }
-
-  /** Asserts that the given nodes have not been started. */
-  Only assertNotStarted(String... nodes) {
-    return assertAboutNodes(not(STARTED), nodes);
-  }
-
-  /** Asserts that the given nodes have not been cancelled. */
-  Only assertNotCancelled(String... nodes) {
-    return assertAboutNodes(not(CANCELLED), nodes);
-  }
-
-  /** Asserts that no nodes in this tester have been started. */
-  void assertNoStartedNodes() {
-    for (TestFuture future : futures.values()) {
-      assertWithMessage("%s is started", future).that(future.isStarted()).isFalse();
-    }
-  }
-
-  private Only assertAboutNodes(Predicate<? super TestFuture> assertion, String... nodes) {
-    ImmutableSet.Builder<TestFuture> builder = ImmutableSet.builder();
-    for (String node : nodes) {
-      TestFuture future = getOrCreate(node);
-      assertWithMessage("%s is %s", future, assertion).that(assertion.test(future)).isTrue();
-      builder.add(future);
-    }
-    return new Only(builder.build(), assertion);
-  }
-
-  /**
-   * Fluent class for making a previous assertion more strict by specifying that whatever was
-   * asserted should be true only for the specified nodes and not for any others.
-   */
-  final class Only {
-
-    private final ImmutableSet<TestFuture> expected;
-    private final Predicate<? super TestFuture> assertion;
-
-    Only(ImmutableSet<TestFuture> expected, Predicate<? super TestFuture> assertion) {
-      this.expected = checkNotNull(expected);
-      this.assertion = checkNotNull(assertion);
-    }
-
-    /**
-     * Asserts that the previous assertion was not true for any node other than those that were
-     * specified.
-     */
-    void only() {
-      for (TestFuture future : futures.values()) {
-        if (!expected.contains(future)) {
-          assertWithMessage("%s is %s", future, assertion).that(assertion.test(future)).isFalse();
-        }
-      }
-    }
-  }
-
-  /**
-   * A simple future for testing that can be marked as having been started and which can be
-   * completed with a result.
-   */
-  private static final class TestFuture extends AbstractFuture<String> {
-
-    private final String name;
-    private volatile boolean started;
-
-    private TestFuture(String name) {
-      this.name = checkNotNull(name);
-    }
-
-    /** Marks this future as having been started and returns it. */
-    TestFuture start() {
-      this.started = true;
-      return this;
-    }
-
-    /** Returns whether or not this future's task was started. */
-    boolean isStarted() {
-      return started;
-    }
-
-    /** Completes this future's task by setting a value for it. */
-    public void complete() {
-      super.set("completed");
-    }
-
-    @Override
-    public String toString() {
-      return name;
-    }
-  }
-
-  private static final Predicate<TestFuture> STARTED =
-      new Predicate<TestFuture>() {
-        @Override
-        public boolean test(TestFuture future) {
-          return future.isStarted();
-        }
-
-        @Override
-        public String toString() {
-          return "started";
-        }
-      };
-
-  private static final Predicate<TestFuture> CANCELLED =
-      new Predicate<TestFuture>() {
-        @Override
-        public boolean test(TestFuture future) {
-          return future.isCancelled();
-        }
-
-        @Override
-        public String toString() {
-          return "cancelled";
-        }
-      };
-
-  /** Version of Predicates.not with a toString() that's nicer for our assertion error messages. */
-  private static <T> Predicate<T> not(final Predicate<T> predicate) {
-    return new Predicate<T>() {
-      @Override
-      public boolean test(T input) {
-        return !predicate.test(input);
-      }
-
-      @Override
-      public String toString() {
-        return "not " + predicate;
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/functional/producers/fluentfuture/FluentFutures.java b/javatests/dagger/functional/producers/fluentfuture/FluentFutures.java
deleted file mode 100644
index 7bb25f6..0000000
--- a/javatests/dagger/functional/producers/fluentfuture/FluentFutures.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.producers.fluentfuture;
-
-import static com.google.common.util.concurrent.Futures.immediateFuture;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.BindsInstance;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-final class FluentFutures {
-  interface Dependency {
-    FluentFuture<Float> floatFuture();
-  }
-
-  @ProducerModule
-  static final class Module {
-    @Produces
-    static FluentFuture<Integer> intFuture() {
-      return FluentFuture.from(immediateFuture(5));
-    }
-
-    @Produces
-    static FluentFuture<String> stringFuture(int i) {
-      return FluentFuture.from(immediateFuture("hello"));
-    }
-
-    @Produces
-    @IntoSet
-    static FluentFuture<Double> doubleFuture(int i) {
-      return FluentFuture.from(immediateFuture((double) i));
-    }
-
-    @Produces
-    @IntoSet
-    static double dependencyInput(float f) {
-      return (double) f;
-    }
-
-    @Produces
-    @ElementsIntoSet
-    static Set<FluentFuture<Double>> setOfDoubleFutures(int i) {
-      return ImmutableSet.of(
-          FluentFuture.from(immediateFuture((double) i + 1)),
-          FluentFuture.from(immediateFuture((double) i + 2)));
-    }
-  }
-
-  @ProductionComponent(modules = Module.class, dependencies = Dependency.class)
-  interface Component {
-    ListenableFuture<String> string();
-
-    ListenableFuture<Set<Double>> setOfDouble();
-
-    @ProductionComponent.Builder
-    interface Builder {
-      Builder dependency(Dependency dependency);
-
-      @BindsInstance
-      Builder executor(@Production Executor executor);
-
-      Component build();
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/fluentfuture/FluentFuturesTest.java b/javatests/dagger/functional/producers/fluentfuture/FluentFuturesTest.java
deleted file mode 100644
index 8745860..0000000
--- a/javatests/dagger/functional/producers/fluentfuture/FluentFuturesTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.producers.fluentfuture;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.util.concurrent.Futures.immediateFuture;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import com.google.common.util.concurrent.FluentFuture;
-import dagger.functional.producers.fluentfuture.FluentFutures.Component;
-import dagger.functional.producers.fluentfuture.FluentFutures.Dependency;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class FluentFuturesTest {
-
-  @Test
-  public void testFluentFutures() throws Exception {
-    Component component =
-        DaggerFluentFutures_Component.builder()
-            .executor(directExecutor())
-            .dependency(
-                new Dependency() {
-                  @Override
-                  public FluentFuture<Float> floatFuture() {
-                    return FluentFuture.from(immediateFuture(42.0f));
-                  }
-                })
-            .build();
-    assertThat(component.string().isDone()).isTrue();
-    assertThat(component.string().get()).isEqualTo("hello");
-    assertThat(component.setOfDouble().isDone()).isTrue();
-    assertThat(component.setOfDouble().get()).containsExactly(5.0, 6.0, 7.0, 42.0);
-  }
-}
diff --git a/javatests/dagger/functional/producers/gwt/GwtIncompatibles.java b/javatests/dagger/functional/producers/gwt/GwtIncompatibles.java
deleted file mode 100644
index 75efd96..0000000
--- a/javatests/dagger/functional/producers/gwt/GwtIncompatibles.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.producers.gwt;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.lang.annotation.Retention;
-
-interface GwtIncompatibles {
-  @Retention(RUNTIME)
-  @interface GwtIncompatible {}
-
-  @GwtIncompatible
-  @ProducerModule
-  class OnModule {
-    @Produces
-    static String onModule() {
-      return "on module";
-    }
-  }
-
-  @ProducerModule
-  class OnMethod {
-    @GwtIncompatible
-    @Produces
-    static String onMethod() {
-      return "on method";
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/gwt/GwtIncompatiblesTest.java b/javatests/dagger/functional/producers/gwt/GwtIncompatiblesTest.java
deleted file mode 100644
index d484c8c..0000000
--- a/javatests/dagger/functional/producers/gwt/GwtIncompatiblesTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.producers.gwt;
-
-import dagger.functional.producers.gwt.GwtIncompatibles.GwtIncompatible;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@code @GwtIncompatible} bindings. */
-@RunWith(JUnit4.class)
-public class GwtIncompatiblesTest {
-  @Test
-  public void testIncompatible() {
-    assertGwtIncompatible(GwtIncompatibles_OnModule_OnModuleFactory.class);
-    assertGwtIncompatible(GwtIncompatibles_OnMethod_OnMethodFactory.class);
-  }
-
-  private void assertGwtIncompatible(Class<?> clazz) {
-    boolean gwtIncompatible = clazz.isAnnotationPresent(GwtIncompatible.class);
-    if (!gwtIncompatible) {
-      throw new AssertionError(clazz.getCanonicalName() + " is not @GwtIncompatible");
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/MonitoredComponent.java b/javatests/dagger/functional/producers/monitoring/MonitoredComponent.java
deleted file mode 100644
index 2df5645..0000000
--- a/javatests/dagger/functional/producers/monitoring/MonitoredComponent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProductionComponent;
-
-@ProductionComponent(
-  modules = {ExecutorModule.class, MonitoringModule.class, StubModule.class, ServingModule.class}
-)
-interface MonitoredComponent {
-  ListenableFuture<String> output();
-}
diff --git a/javatests/dagger/functional/producers/monitoring/MonitoringModule.java b/javatests/dagger/functional/producers/monitoring/MonitoringModule.java
deleted file mode 100644
index 3c08255..0000000
--- a/javatests/dagger/functional/producers/monitoring/MonitoringModule.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-
-@Module
-final class MonitoringModule {
-  private final ProductionComponentMonitor.Factory monitorFactory;
-
-  MonitoringModule(ProductionComponentMonitor.Factory monitorFactory) {
-    this.monitorFactory = monitorFactory;
-  }
-
-  @Provides
-  @IntoSet
-  ProductionComponentMonitor.Factory monitorFactory() {
-    return monitorFactory;
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/MonitoringTest.java b/javatests/dagger/functional/producers/monitoring/MonitoringTest.java
deleted file mode 100644
index 543835f..0000000
--- a/javatests/dagger/functional/producers/monitoring/MonitoringTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** Tests for production components using monitoring. */
-@RunWith(JUnit4.class)
-public final class MonitoringTest {
-  @Mock private ProductionComponentMonitor.Factory componentMonitorFactory;
-  @Mock private StringStub server1;
-  @Mock private StringStub server2;
-  private SettableFuture<String> server1Future;
-  private SettableFuture<String> server2Future;
-  private FakeProductionComponentMonitor componentMonitor;
-
-  @Before
-  public void setUp() {
-    MockitoAnnotations.initMocks(this);
-    componentMonitor = new FakeProductionComponentMonitor();
-    when(componentMonitorFactory.create(any())).thenReturn(componentMonitor);
-    server1Future = SettableFuture.create();
-    server2Future = SettableFuture.create();
-    when(server1.run(any(String.class))).thenReturn(server1Future);
-    when(server2.run(any(String.class))).thenReturn(server2Future);
-  }
-
-  @Test
-  public void basicMonitoring() throws Exception {
-    MonitoredComponent component =
-        DaggerMonitoredComponent.builder()
-            .monitoringModule(new MonitoringModule(componentMonitorFactory))
-            .stubModule(new StubModule(server1, server2))
-            .build();
-    ListenableFuture<String> output = component.output();
-    assertThat(componentMonitor.monitors).hasSize(3);
-    ImmutableList<Map.Entry<ProducerToken, ProducerMonitor>> entries =
-        ImmutableList.copyOf(componentMonitor.monitors.entrySet());
-    assertThat(entries.get(0).getKey().toString()).contains("CallServer2");
-    assertThat(entries.get(1).getKey().toString()).contains("CallServer1");
-    assertThat(entries.get(2).getKey().toString()).contains("RequestData");
-
-    ProducerMonitor callServer2Monitor = entries.get(0).getValue();
-    ProducerMonitor callServer1Monitor = entries.get(1).getValue();
-    ProducerMonitor requestDataMonitor = entries.get(2).getValue();
-
-    InOrder inOrder = inOrder(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-    inOrder.verify(callServer2Monitor).requested();
-    inOrder.verify(callServer1Monitor).requested();
-    inOrder.verify(requestDataMonitor).requested();
-    inOrder.verify(requestDataMonitor).ready();
-    inOrder.verify(requestDataMonitor).methodStarting();
-    inOrder.verify(requestDataMonitor).methodFinished();
-    inOrder.verify(requestDataMonitor).succeeded("Hello, World!");
-    inOrder.verify(callServer1Monitor).ready();
-    inOrder.verify(callServer1Monitor).methodStarting();
-    inOrder.verify(callServer1Monitor).methodFinished();
-    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-
-    server1Future.set("server 1 response");
-    inOrder.verify(callServer1Monitor).succeeded("server 1 response");
-    inOrder.verify(callServer2Monitor).ready();
-    inOrder.verify(callServer2Monitor).methodStarting();
-    inOrder.verify(callServer2Monitor).methodFinished();
-    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-
-    server2Future.set("server 2 response");
-    inOrder.verify(callServer2Monitor).succeeded("server 2 response");
-    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-    assertThat(output.get()).isEqualTo("server 2 response");
-  }
-
-  @Test
-  public void basicMonitoringWithFailure() throws Exception {
-    MonitoredComponent component =
-        DaggerMonitoredComponent.builder()
-            .monitoringModule(new MonitoringModule(componentMonitorFactory))
-            .stubModule(new StubModule(server1, server2))
-            .build();
-    ListenableFuture<String> output = component.output();
-    assertThat(componentMonitor.monitors).hasSize(3);
-    ImmutableList<Map.Entry<ProducerToken, ProducerMonitor>> entries =
-        ImmutableList.copyOf(componentMonitor.monitors.entrySet());
-    assertThat(entries.get(0).getKey().toString()).contains("CallServer2");
-    assertThat(entries.get(1).getKey().toString()).contains("CallServer1");
-    assertThat(entries.get(2).getKey().toString()).contains("RequestData");
-
-    ProducerMonitor callServer2Monitor = entries.get(0).getValue();
-    ProducerMonitor callServer1Monitor = entries.get(1).getValue();
-    ProducerMonitor requestDataMonitor = entries.get(2).getValue();
-
-    InOrder inOrder = inOrder(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-    inOrder.verify(callServer2Monitor).requested();
-    inOrder.verify(callServer1Monitor).requested();
-    inOrder.verify(requestDataMonitor).requested();
-    inOrder.verify(requestDataMonitor).ready();
-    inOrder.verify(requestDataMonitor).methodStarting();
-    inOrder.verify(requestDataMonitor).methodFinished();
-    inOrder.verify(requestDataMonitor).succeeded("Hello, World!");
-    inOrder.verify(callServer1Monitor).ready();
-    inOrder.verify(callServer1Monitor).methodStarting();
-    inOrder.verify(callServer1Monitor).methodFinished();
-    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-
-    RuntimeException cause = new RuntimeException("monkey");
-    server1Future.setException(cause);
-    inOrder.verify(callServer1Monitor).failed(cause);
-    inOrder.verify(callServer2Monitor).ready();
-    inOrder.verify(callServer2Monitor).failed(any(Throwable.class));
-    verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor);
-    try {
-      output.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(Throwables.getRootCause(e)).isSameInstanceAs(cause);
-    }
-  }
-
-  private static final class FakeProductionComponentMonitor extends ProductionComponentMonitor {
-    final Map<ProducerToken, ProducerMonitor> monitors = new LinkedHashMap<>();
-
-    @Override
-    public ProducerMonitor producerMonitorFor(ProducerToken token) {
-      ProducerMonitor monitor = mock(ProducerMonitor.class);
-      monitors.put(token, monitor);
-      return monitor;
-    }
-  }
-
-  @Test
-  public void monitoringWithThreads() throws Exception {
-    ThreadRecordingProductionComponentMonitor componentMonitor =
-        new ThreadRecordingProductionComponentMonitor();
-    when(componentMonitorFactory.create(any())).thenReturn(componentMonitor);
-
-    ThreadMonitoredComponent component =
-        DaggerThreadMonitoredComponent.builder()
-            .monitoringModule(new MonitoringModule(componentMonitorFactory))
-            .executorModule(new ExecutorModule(Executors.newFixedThreadPool(10)))
-            .build();
-    ThreadAccumulator threadAccumulator = component.threadAccumulator().get();
-
-    assertThat(componentMonitor.monitors).hasSize(3);
-    ImmutableList<Map.Entry<ProducerToken, ThreadRecordingProducerMonitor>> entries =
-        ImmutableList.copyOf(componentMonitor.monitors.entrySet());
-
-    assertThat(entries.get(0).getKey().toString()).contains("EntryPoint");
-    ThreadRecordingProducerMonitor entryPointMonitor = entries.get(0).getValue();
-    assertThat(entries.get(1).getKey().toString()).contains("Required");
-    ThreadRecordingProducerMonitor requiredMonitor = entries.get(1).getValue();
-    assertThat(entries.get(2).getKey().toString()).contains("Deferred");
-    ThreadRecordingProducerMonitor deferredMonitor = entries.get(2).getValue();
-
-    // The entry point producer was requested from the main thread, then ran in its own thread.
-    assertThat(entryPointMonitor.requestedThreadId).isEqualTo(Thread.currentThread().getId());
-    assertThat(entryPointMonitor.startingThreadId)
-        .isEqualTo(threadAccumulator.threadId("entryPoint"));
-    assertThat(entryPointMonitor.finishedThreadId)
-        .isEqualTo(threadAccumulator.threadId("entryPoint"));
-
-    // The deferred producer was requested by the required producer, then ran in its own thread.
-    assertThat(deferredMonitor.requestedThreadId).isEqualTo(threadAccumulator.threadId("required"));
-    assertThat(deferredMonitor.startingThreadId).isEqualTo(threadAccumulator.threadId("deferred"));
-    assertThat(deferredMonitor.finishedThreadId).isEqualTo(threadAccumulator.threadId("deferred"));
-
-    // The required producer was requested by the entry point producer, then ran in its own thread.
-    assertThat(requiredMonitor.requestedThreadId).isEqualTo(entryPointMonitor.requestedThreadId);
-    assertThat(requiredMonitor.startingThreadId).isEqualTo(threadAccumulator.threadId("required"));
-    assertThat(requiredMonitor.finishedThreadId).isEqualTo(threadAccumulator.threadId("required"));
-
-    // Each producer ran in a distinct thread.
-    ImmutableSet<Long> threadIds =
-        ImmutableSet.of(
-            Thread.currentThread().getId(),
-            threadAccumulator.threadId("required"),
-            threadAccumulator.threadId("deferred"),
-            threadAccumulator.threadId("entryPoint"));
-    assertThat(threadIds).hasSize(4);
-  }
-
-  private static final class ThreadRecordingProductionComponentMonitor
-      extends ProductionComponentMonitor {
-    final Map<ProducerToken, ThreadRecordingProducerMonitor> monitors = new LinkedHashMap<>();
-
-    @Override
-    public ProducerMonitor producerMonitorFor(ProducerToken token) {
-      ThreadRecordingProducerMonitor monitor = new ThreadRecordingProducerMonitor();
-      monitors.put(token, monitor);
-      return monitor;
-    }
-  }
-
-  private static final class ThreadRecordingProducerMonitor extends ProducerMonitor {
-    private long requestedThreadId;
-    private long startingThreadId;
-    private long finishedThreadId;
-
-    @Override
-    public void requested() {
-      requestedThreadId = Thread.currentThread().getId();
-    }
-
-    @Override
-    public void methodStarting() {
-      startingThreadId = Thread.currentThread().getId();
-    }
-
-    @Override
-    public void methodFinished() {
-      finishedThreadId = Thread.currentThread().getId();
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/ServingModule.java b/javatests/dagger/functional/producers/monitoring/ServingModule.java
deleted file mode 100644
index 09c9cd1..0000000
--- a/javatests/dagger/functional/producers/monitoring/ServingModule.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.monitoring.StubModule.ForServer1;
-import dagger.functional.producers.monitoring.StubModule.ForServer2;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import javax.inject.Qualifier;
-
-@ProducerModule
-final class ServingModule {
-  @Qualifier
-  @interface RequestData {}
-
-  @Qualifier
-  @interface IntermediateData {}
-
-  @Produces
-  @RequestData
-  static String requestData() {
-    return "Hello, World!";
-  }
-
-  @Produces
-  @IntermediateData
-  static ListenableFuture<String> callServer1(
-      @RequestData String data, @ForServer1 StringStub stub) {
-    return stub.run(data);
-  }
-
-  @Produces
-  static ListenableFuture<String> callServer2(
-      @IntermediateData String data, @ForServer2 StringStub stub) {
-    return stub.run(data);
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/StringStub.java b/javatests/dagger/functional/producers/monitoring/StringStub.java
deleted file mode 100644
index 2553e88..0000000
--- a/javatests/dagger/functional/producers/monitoring/StringStub.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-interface StringStub {
-  ListenableFuture<String> run(String input);
-}
diff --git a/javatests/dagger/functional/producers/monitoring/StubModule.java b/javatests/dagger/functional/producers/monitoring/StubModule.java
deleted file mode 100644
index 3c5893c..0000000
--- a/javatests/dagger/functional/producers/monitoring/StubModule.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.producers.monitoring;
-
-import dagger.Module;
-import dagger.Provides;
-import javax.inject.Qualifier;
-
-@Module
-final class StubModule {
-  @Qualifier
-  @interface ForServer1 {}
-
-  @Qualifier
-  @interface ForServer2 {}
-
-  private final StringStub server1;
-  private final StringStub server2;
-
-  StubModule(StringStub server1, StringStub server2) {
-    this.server1 = server1;
-    this.server2 = server2;
-  }
-
-  @Provides
-  @ForServer1
-  StringStub server1() {
-    return server1;
-  }
-
-  @Provides
-  @ForServer2
-  StringStub server2() {
-    return server2;
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/ThreadAccumulator.java b/javatests/dagger/functional/producers/monitoring/ThreadAccumulator.java
deleted file mode 100644
index 3d95fb6..0000000
--- a/javatests/dagger/functional/producers/monitoring/ThreadAccumulator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.monitoring;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-final class ThreadAccumulator {
-  private final Map<String, Long> threadIds = new ConcurrentHashMap<>();
-
-  @Inject
-  ThreadAccumulator() {}
-
-  void markThread(String name) {
-    threadIds.put(name, Thread.currentThread().getId());
-  }
-
-  long threadId(String name) {
-    return threadIds.get(name);
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/ThreadModule.java b/javatests/dagger/functional/producers/monitoring/ThreadModule.java
deleted file mode 100644
index f55c3e0..0000000
--- a/javatests/dagger/functional/producers/monitoring/ThreadModule.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.monitoring;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.monitoring.ThreadQualifiers.Deferred;
-import dagger.functional.producers.monitoring.ThreadQualifiers.EntryPoint;
-import dagger.functional.producers.monitoring.ThreadQualifiers.Required;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-@ProducerModule
-final class ThreadModule {
-  @Produces
-  @Deferred
-  Object deferred(ThreadAccumulator acc) {
-    acc.markThread("deferred");
-    return new Object();
-  }
-
-  @Produces
-  @Required
-  ListenableFuture<Object> required(@Deferred Producer<Object> o, ThreadAccumulator acc) {
-    acc.markThread("required");
-    return o.get();
-  }
-
-  @Produces
-  @EntryPoint
-  ThreadAccumulator entryPoint(@Required Object o, ThreadAccumulator acc) {
-    acc.markThread("entryPoint");
-    return acc;
-  }
-}
diff --git a/javatests/dagger/functional/producers/monitoring/ThreadMonitoredComponent.java b/javatests/dagger/functional/producers/monitoring/ThreadMonitoredComponent.java
deleted file mode 100644
index 576cd7f..0000000
--- a/javatests/dagger/functional/producers/monitoring/ThreadMonitoredComponent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.monitoring;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.functional.producers.monitoring.ThreadQualifiers.EntryPoint;
-import dagger.producers.ProductionComponent;
-import javax.inject.Singleton;
-
-@Singleton
-@ProductionComponent(modules = {ExecutorModule.class, MonitoringModule.class, ThreadModule.class})
-interface ThreadMonitoredComponent {
-  @EntryPoint
-  ListenableFuture<ThreadAccumulator> threadAccumulator();
-}
diff --git a/javatests/dagger/functional/producers/monitoring/ThreadQualifiers.java b/javatests/dagger/functional/producers/monitoring/ThreadQualifiers.java
deleted file mode 100644
index 59ccbe4..0000000
--- a/javatests/dagger/functional/producers/monitoring/ThreadQualifiers.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.monitoring;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-final class ThreadQualifiers {
-  private ThreadQualifiers() {}
-
-  @Qualifier
-  @Retention(RUNTIME)
-  @Documented
-  @interface EntryPoint {}
-
-  @Qualifier
-  @Retention(RUNTIME)
-  @Documented
-  @interface Required {}
-
-  @Qualifier
-  @Retention(RUNTIME)
-  @Documented
-  @interface Deferred {}
-}
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java b/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java
deleted file mode 100644
index fa5c6ee..0000000
--- a/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.multibindings;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.functional.producers.multibindings.Qualifiers.EmptyButDeclaredInModule;
-import dagger.functional.producers.multibindings.Qualifiers.EmptyButDeclaredInModuleAndProducerModule;
-import dagger.functional.producers.multibindings.Qualifiers.ObjCount;
-import dagger.functional.producers.multibindings.Qualifiers.OnlyProvisionMultibindings;
-import dagger.functional.producers.multibindings.Qualifiers.PossiblyThrowingMap;
-import dagger.functional.producers.multibindings.Qualifiers.PossiblyThrowingSet;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.ProductionComponent;
-import java.util.Map;
-import java.util.Set;
-
-@ProductionComponent(
-  modules = {ExecutorModule.class, MultibindingProducerModule.class, MultibindingModule.class}
-)
-interface MultibindingComponent {
-  ListenableFuture<Set<String>> strs();
-  ListenableFuture<Integer> strCount();
-
-  ListenableFuture<Set<Produced<String>>> successfulSet();
-
-  @PossiblyThrowingSet
-  ListenableFuture<Set<Produced<String>>> possiblyThrowingSet();
-
-  ListenableFuture<Map<Integer, String>> map();
-
-  ListenableFuture<Map<Integer, Producer<String>>> mapOfProducer();
-
-  ListenableFuture<Map<Integer, Produced<String>>> mapOfProduced();
-
-  @PossiblyThrowingMap
-  ListenableFuture<Map<Integer, String>> possiblyThrowingMap();
-
-  @PossiblyThrowingMap
-  ListenableFuture<Map<Integer, Producer<String>>> possiblyThrowingMapOfProducer();
-
-  @PossiblyThrowingMap
-  ListenableFuture<Map<Integer, Produced<String>>> possiblyThrowingMapOfProduced();
-
-  ListenableFuture<Set<Object>> objs();
-
-  ListenableFuture<Set<Produced<Object>>> producedObjs();
-
-  ListenableFuture<Map<Object, Object>> objMap();
-
-  ListenableFuture<Map<Object, Produced<Object>>> objMapOfProduced();
-
-  ListenableFuture<Map<Object, Producer<Object>>> objMapOfProducer();
-
-  @ObjCount
-  ListenableFuture<Integer> objCount();
-
-  @EmptyButDeclaredInModuleAndProducerModule
-  ListenableFuture<Map<String, Object>> emptyButDeclaredInModuleAndProducerModule();
-
-  @EmptyButDeclaredInModule
-  ListenableFuture<Map<String, Object>> emptyButDeclaredInModule();
-
-  @OnlyProvisionMultibindings
-  ListenableFuture<Map<String, Object>> onlyProvisionMultibindings();
-}
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingModule.java b/javatests/dagger/functional/producers/multibindings/MultibindingModule.java
deleted file mode 100644
index 08ed6d7..0000000
--- a/javatests/dagger/functional/producers/multibindings/MultibindingModule.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.multibindings;
-
-import com.google.common.collect.ImmutableSet;
-import dagger.Module;
-import dagger.Provides;
-import dagger.functional.producers.multibindings.Qualifiers.EmptyButDeclaredInModule;
-import dagger.functional.producers.multibindings.Qualifiers.EmptyButDeclaredInModuleAndProducerModule;
-import dagger.functional.producers.multibindings.Qualifiers.OnlyProvisionMultibindings;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.multibindings.Multibinds;
-import dagger.multibindings.StringKey;
-import java.util.Map;
-import java.util.Set;
-
-@Module
-abstract class MultibindingModule {
-  @Provides
-  @IntoSet
-  static String providedStr() {
-    return "providedStr";
-  }
-
-  @Provides
-  @ElementsIntoSet
-  static Set<String> providedStrs() {
-    return ImmutableSet.of("providedStr1", "providedStr2");
-  }
-
-  @Provides
-  @IntoMap
-  @IntKey(3)
-  static String providedValueFor3() {
-    return "provided three";
-  }
-  
-  @Multibinds
-  @EmptyButDeclaredInModuleAndProducerModule
-  abstract Map<String, Object> emptyButDeclaredInModuleAndProducerModule();
-
-  @Multibinds
-  @EmptyButDeclaredInModule
-  abstract Map<String, Object> emptyButDeclaredInModule();
-
-  @Provides
-  @IntoMap
-  @StringKey("a")
-  @OnlyProvisionMultibindings
-  static Object onlyProvisionMultibindings() {
-    return "only multibinding";
-  }
-}
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java b/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java
deleted file mode 100644
index 350733b..0000000
--- a/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.multibindings;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.multibindings.Qualifiers.EmptyButDeclaredInModuleAndProducerModule;
-import dagger.functional.producers.multibindings.Qualifiers.ObjCount;
-import dagger.functional.producers.multibindings.Qualifiers.PossiblyThrowingMap;
-import dagger.functional.producers.multibindings.Qualifiers.PossiblyThrowingSet;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.multibindings.Multibinds;
-import dagger.producers.Produced;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.util.Map;
-import java.util.Set;
-
-@ProducerModule
-abstract class MultibindingProducerModule {
-  @Produces
-  @IntoSet
-  static ListenableFuture<String> futureStr() {
-    return Futures.immediateFuture("foo");
-  }
-
-  @Produces
-  @IntoSet
-  static String str() {
-    return "bar";
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static ListenableFuture<Set<String>> futureStrs() {
-    return Futures.<Set<String>>immediateFuture(ImmutableSet.of("foo1", "foo2"));
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static Set<ListenableFuture<String>> strFutures() {
-    return ImmutableSet.of(Futures.immediateFuture("baz1"), Futures.immediateFuture("baz2"));
-  }
-
-  @Produces
-  @ElementsIntoSet
-  static Set<String> strs() {
-    return ImmutableSet.of("bar1", "bar2");
-  }
-
-  @Produces
-  static int strCount(Set<String> strs) {
-    return strs.size();
-  }
-
-  @Produces
-  @IntoSet
-  @PossiblyThrowingSet
-  static String successfulStringForSet() {
-    return "singleton";
-  }
-
-  @Produces
-  @ElementsIntoSet
-  @PossiblyThrowingSet
-  static Set<String> successfulStringsForSet() {
-    return ImmutableSet.of("double", "ton");
-  }
-
-  @Produces
-  @IntoSet
-  @PossiblyThrowingSet
-  static String throwingStringForSet() {
-    throw new RuntimeException("monkey");
-  }
-
-  @Produces
-  @IntoMap
-  @IntKey(42)
-  static ListenableFuture<String> futureFor42() {
-    return Futures.immediateFuture("forty two");
-  }
-
-  @Produces
-  @IntoMap
-  @IntKey(15)
-  static String valueFor15() {
-    return "fifteen";
-  }
-
-  @Produces
-  @IntoMap
-  @PossiblyThrowingMap
-  @IntKey(42)
-  static ListenableFuture<String> successfulFutureFor42() {
-    return Futures.immediateFuture("forty two");
-  }
-
-  @Produces
-  @IntoMap
-  @PossiblyThrowingMap
-  @IntKey(15)
-  static String throwingValueFor15() {
-    throw new RuntimeException("monkey");
-  }
-
-  @Multibinds
-  abstract Set<Object> objs();
-
-  @Multibinds
-  abstract Map<Object, Object> objMap();
-
-  @Produces
-  @ObjCount
-  static int objCount(Set<Produced<Object>> objs, Map<Object, Produced<Object>> objMap) {
-    return objs.size() + objMap.size();
-  }
-  
-  @Multibinds
-  @EmptyButDeclaredInModuleAndProducerModule
-  abstract Map<String, Object> emptyButDeclaredInModuleAndProducerModule();
-}
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingTest.java b/javatests/dagger/functional/producers/multibindings/MultibindingTest.java
deleted file mode 100644
index 81daa88..0000000
--- a/javatests/dagger/functional/producers/multibindings/MultibindingTest.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.multibindings;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MultibindingTest {
-  @Test
-  public void setBinding() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    assertThat(multibindingComponent.strs().get())
-        .containsExactly(
-            "foo",
-            "foo1",
-            "foo2",
-            "baz1",
-            "baz2",
-            "bar",
-            "bar1",
-            "bar2",
-            "providedStr",
-            "providedStr1",
-            "providedStr2");
-    assertThat(multibindingComponent.strCount().get()).isEqualTo(11);
-  }
-
-  @Test
-  public void setBindingOfProduced() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    assertThat(multibindingComponent.successfulSet().get())
-        .containsExactly(
-            Produced.successful("foo"),
-            Produced.successful("foo1"),
-            Produced.successful("foo2"),
-            Produced.successful("baz1"),
-            Produced.successful("baz2"),
-            Produced.successful("bar"),
-            Produced.successful("bar1"),
-            Produced.successful("bar2"),
-            Produced.successful("providedStr"),
-            Produced.successful("providedStr1"),
-            Produced.successful("providedStr2"));
-  }
-
-  @Test
-  public void setBindingOfProducedWithFailures() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Set<Produced<String>> possiblyThrowingSet = multibindingComponent.possiblyThrowingSet().get();
-    Set<String> successes = new HashSet<>();
-    Set<ExecutionException> failures = new HashSet<>();
-    for (Produced<String> str : possiblyThrowingSet) {
-      try {
-        successes.add(str.get());
-      } catch (ExecutionException e) {
-        failures.add(e);
-      }
-    }
-    assertThat(successes).containsExactly("singleton", "double", "ton");
-    assertThat(failures).hasSize(1);
-    assertThat(Iterables.getOnlyElement(failures).getCause()).hasMessageThat().isEqualTo("monkey");
-  }
-
-  @Test
-  public void mapBinding() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Map<Integer, String> map = multibindingComponent.map().get();
-    assertThat(map).hasSize(3);
-    assertThat(map).containsEntry(15, "fifteen");
-    assertThat(map).containsEntry(42, "forty two");
-    assertThat(map).containsEntry(3, "provided three");
-  }
-
-  @Test
-  public void mapOfProducerBinding() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Map<Integer, Producer<String>> map = multibindingComponent.mapOfProducer().get();
-    assertThat(map).hasSize(3);
-    assertThat(map).containsKey(15);
-    assertThat(map.get(15).get().get()).isEqualTo("fifteen");
-    assertThat(map).containsKey(42);
-    assertThat(map.get(42).get().get()).isEqualTo("forty two");
-    assertThat(map).containsKey(3);
-    assertThat(map.get(3).get().get()).isEqualTo("provided three");
-  }
-
-  @Test
-  public void mapOfProducedBinding() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Map<Integer, Produced<String>> map = multibindingComponent.mapOfProduced().get();
-    assertThat(map).hasSize(3);
-    assertThat(map).containsKey(15);
-    assertThat(map.get(15).get()).isEqualTo("fifteen");
-    assertThat(map).containsKey(42);
-    assertThat(map.get(42).get()).isEqualTo("forty two");
-    assertThat(map).containsKey(3);
-    assertThat(map.get(3).get()).isEqualTo("provided three");
-  }
-
-  @Test
-  public void mapBindingWithFailures() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    try {
-      multibindingComponent.possiblyThrowingMap().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e.getCause()).hasMessageThat().isEqualTo("monkey");
-    }
-  }
-
-  @Test
-  public void mapOfProducerBindingWithFailures() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Map<Integer, Producer<String>> map =
-        multibindingComponent.possiblyThrowingMapOfProducer().get();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsKey(42);
-    assertThat(map.get(42).get().get()).isEqualTo("forty two");
-    assertThat(map).containsKey(15);
-    ListenableFuture<String> future = map.get(15).get();
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e.getCause()).hasMessageThat().isEqualTo("monkey");
-    }
-  }
-
-  @Test
-  public void mapOfProducedBindingWithFailures() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    Map<Integer, Produced<String>> map =
-        multibindingComponent.possiblyThrowingMapOfProduced().get();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsKey(42);
-    assertThat(map.get(42).get()).isEqualTo("forty two");
-    assertThat(map).containsKey(15);
-    Produced<String> produced = map.get(15);
-    try {
-      produced.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e.getCause()).hasMessageThat().isEqualTo("monkey");
-    }
-  }
-
-  @Test
-  public void emptySet() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    assertThat(multibindingComponent.objs().get()).isEmpty();
-    assertThat(multibindingComponent.producedObjs().get()).isEmpty();
-    assertThat(multibindingComponent.objCount().get()).isEqualTo(0);
-  }
-
-  @Test
-  public void emptyMap() throws Exception {
-    MultibindingComponent multibindingComponent = DaggerMultibindingComponent.create();
-    assertThat(multibindingComponent.objMap().get()).isEmpty();
-    assertThat(multibindingComponent.objMapOfProduced().get()).isEmpty();
-    assertThat(multibindingComponent.objMapOfProducer().get()).isEmpty();
-  }
-}
diff --git a/javatests/dagger/functional/producers/multibindings/Qualifiers.java b/javatests/dagger/functional/producers/multibindings/Qualifiers.java
deleted file mode 100644
index 640430c..0000000
--- a/javatests/dagger/functional/producers/multibindings/Qualifiers.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.multibindings;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-final class Qualifiers {
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface PossiblyThrowingSet {}
-
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface PossiblyThrowingMap {}
-
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface ObjCount {}
-
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface EmptyButDeclaredInModule {}
-
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface EmptyButDeclaredInModuleAndProducerModule {}
-
-  @Documented
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface OnlyProvisionMultibindings {}
-
-  private Qualifiers() {}
-}
diff --git a/javatests/dagger/functional/producers/optional/OptionalBindingComponents.java b/javatests/dagger/functional/producers/optional/OptionalBindingComponents.java
deleted file mode 100644
index d3a7aa6..0000000
--- a/javatests/dagger/functional/producers/optional/OptionalBindingComponents.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.optional;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.Provides;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.lang.annotation.Retention;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import javax.annotation.Nullable;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-/** Classes to support testing {@code BindsOptionalOf} functionality. */
-final class OptionalBindingComponents {
-
-  /** A qualifier. */
-  @Qualifier
-  @Retention(RUNTIME)
-  @interface SomeQualifier {}
-
-  /** A value object that contains various optionally-bound objects. */
-  @AutoValue
-  abstract static class Values {
-    abstract Optional<Value> optionalInstance();
-
-    abstract Optional<Producer<Value>> optionalProducer();
-
-    abstract Optional<Produced<Value>> optionalProduced();
-  }
-
-  enum Value {
-    VALUE,
-    QUALIFIED_VALUE
-  }
-
-  @Module
-  static final class ExecutorModule {
-    @Provides
-    @Production
-    static Executor executor() {
-      return Executors.newSingleThreadExecutor();
-    }
-  }
-
-  /** Binds optionals and {@link Values}. */
-  @ProducerModule
-  abstract static class OptionalBindingModule {
-    @BindsOptionalOf
-    abstract Value value();
-
-    @BindsOptionalOf
-    @SomeQualifier
-    abstract Value qualifiedValue();
-
-    @BindsOptionalOf
-    abstract Object nullableObject();
-
-    @Produces
-    static Values values(
-        Optional<Value> optionalInstance,
-        Optional<Producer<Value>> optionalProducer,
-        Optional<Produced<Value>> optionalProduced) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProducer, optionalProduced);
-    }
-
-    @Produces
-    @SomeQualifier
-    static Values qualifiedValues(
-        Optional<Value> optionalInstance,
-        Optional<Producer<Value>> optionalProducer,
-        Optional<Produced<Value>> optionalProduced) {
-      return new AutoValue_OptionalBindingComponents_Values(
-          optionalInstance, optionalProducer, optionalProduced);
-    }
-  }
-
-  /** Binds {@link Value} using {@link Producer}s. */
-  @ProducerModule
-  abstract static class ConcreteBindingProducerModule {
-    @Produces
-    static Value value() {
-      return Value.VALUE;
-    }
-
-    @Produces
-    @SomeQualifier
-    static Value qualifiedValue() {
-      return Value.QUALIFIED_VALUE;
-    }
-
-    // @Produces @Nullable has no effect (and ProducesMethodValidator warns when the two are used
-    // together. Use a @Provides method and let it be wrapped into a producerFromProvider for the
-    // purposes of the test
-    @Provides
-    @Nullable
-    static Object nullableObject() {
-      return null;
-    }
-  }
-
-  /** Binds {@link Value} using {@link Provider}s. */
-  @Module
-  abstract static class ConcreteBindingModule {
-    @Provides
-    static Value value() {
-      return Value.VALUE;
-    }
-
-    @Provides
-    @SomeQualifier
-    static Value qualifiedValue() {
-      return Value.QUALIFIED_VALUE;
-    }
-
-    @Provides
-    @Nullable
-    static Object nullableObject() {
-      return null;
-    }
-  }
-
-  interface OptionalBindingComponent {
-    ListenableFuture<Values> values();
-
-    ListenableFuture<Optional<Value>> optionalInstance();
-
-    ListenableFuture<Optional<Producer<Value>>> optionalProducer();
-
-    ListenableFuture<Optional<Produced<Value>>> optionalProduced();
-
-    @SomeQualifier
-    ListenableFuture<Values> qualifiedValues();
-
-    @SomeQualifier
-    ListenableFuture<Optional<Value>> qualifiedOptionalInstance();
-
-    @SomeQualifier
-    ListenableFuture<Optional<Producer<Value>>> qualifiedOptionalProducer();
-
-    @SomeQualifier
-    ListenableFuture<Optional<Produced<Value>>> qualifiedOptionalProduced();
-
-    // Nullable bindings can satisfy optional bindings except for Optional<Foo>.
-    ListenableFuture<Optional<Producer<Object>>> optionalNullableProducer();
-
-    ListenableFuture<Optional<Produced<Object>>> optionalNullableProduced();
-  }
-
-  @ProductionComponent(modules = {ExecutorModule.class, OptionalBindingModule.class})
-  interface AbsentOptionalBindingComponent extends OptionalBindingComponent {
-    PresentOptionalBindingSubcomponent presentChild();
-  }
-
-  @ProductionComponent(
-    modules = {
-      ExecutorModule.class,
-      OptionalBindingModule.class,
-      ConcreteBindingProducerModule.class
-    }
-  )
-  interface PresentOptionalBindingComponent extends OptionalBindingComponent {}
-
-  @ProductionSubcomponent(modules = ConcreteBindingProducerModule.class)
-  interface PresentOptionalBindingSubcomponent extends OptionalBindingComponent {}
-
-  @ProductionComponent(
-    modules = {ExecutorModule.class, OptionalBindingModule.class, ConcreteBindingModule.class}
-  )
-  interface PresentOptionalProvisionBindingComponent extends OptionalBindingComponent {}
-}
diff --git a/javatests/dagger/functional/producers/optional/OptionalBindingComponentsAbsentTest.java b/javatests/dagger/functional/producers/optional/OptionalBindingComponentsAbsentTest.java
deleted file mode 100644
index 4bb7234..0000000
--- a/javatests/dagger/functional/producers/optional/OptionalBindingComponentsAbsentTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.optional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.optional.OptionalBindingComponents.AbsentOptionalBindingComponent;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for absent optional bindings. */
-@RunWith(JUnit4.class)
-public final class OptionalBindingComponentsAbsentTest {
-  private AbsentOptionalBindingComponent absent;
-
-  @Before
-  public void setUp() {
-    absent = DaggerOptionalBindingComponents_AbsentOptionalBindingComponent.create();
-  }
-
-  @Test
-  public void optional() throws Exception {
-    assertThat(absent.optionalInstance().get()).isAbsent();
-  }
-
-  @Test
-  public void optionalProducer() throws Exception {
-    assertThat(absent.optionalProducer().get()).isAbsent();
-  }
-
-  @Test
-  public void optionalProduced() throws Exception {
-    assertThat(absent.optionalProduced().get()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptional() throws Exception {
-    assertThat(absent.qualifiedOptionalInstance().get()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptionalProducer() throws Exception {
-    assertThat(absent.qualifiedOptionalProducer().get()).isAbsent();
-  }
-
-  @Test
-  public void qualifiedOptionalProduced() throws Exception {
-    assertThat(absent.qualifiedOptionalProduced().get()).isAbsent();
-  }
-}
diff --git a/javatests/dagger/functional/producers/optional/OptionalBindingComponentsPresentTest.java b/javatests/dagger/functional/producers/optional/OptionalBindingComponentsPresentTest.java
deleted file mode 100644
index 3e2afd4..0000000
--- a/javatests/dagger/functional/producers/optional/OptionalBindingComponentsPresentTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.optional;
-
-import static com.google.common.truth.Truth.assertThat;
-import static dagger.functional.producers.optional.OptionalBindingComponents.Value.QUALIFIED_VALUE;
-import static dagger.functional.producers.optional.OptionalBindingComponents.Value.VALUE;
-
-import com.google.common.collect.ImmutableList;
-import dagger.functional.producers.optional.OptionalBindingComponents.OptionalBindingComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for present optional bindings. */
-@RunWith(Parameterized.class)
-public final class OptionalBindingComponentsPresentTest {
-
-  @Parameters(name = "{0}")
-  public static Iterable<Object[]> parameters() {
-    return ImmutableList.copyOf(
-        new Object[][] {
-          {DaggerOptionalBindingComponents_PresentOptionalBindingComponent.create()},
-          {DaggerOptionalBindingComponents_AbsentOptionalBindingComponent.create().presentChild()},
-          {DaggerOptionalBindingComponents_PresentOptionalProvisionBindingComponent.create()}
-        });
-  }
-
-  private final OptionalBindingComponent component;
-
-  public OptionalBindingComponentsPresentTest(OptionalBindingComponent component) {
-    this.component = component;
-  }
-
-  @Test
-  public void optional() throws Exception {
-    assertThat(component.optionalInstance().get()).hasValue(VALUE);
-  }
-
-  @Test
-  public void optionalProducer() throws Exception {
-    assertThat(component.optionalProducer().get().get().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void optionalProduced() throws Exception {
-    assertThat(component.optionalProduced().get().get().get()).isEqualTo(VALUE);
-  }
-
-  @Test
-  public void qualifiedOptional() throws Exception {
-    assertThat(component.qualifiedOptionalInstance().get()).hasValue(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalProducer() throws Exception {
-    assertThat(component.qualifiedOptionalProducer().get().get().get().get())
-        .isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void qualifiedOptionalProduced() throws Exception {
-    assertThat(component.qualifiedOptionalProduced().get().get().get()).isEqualTo(QUALIFIED_VALUE);
-  }
-
-  @Test
-  public void optionalNullableProducer() throws Exception {
-    assertThat(component.optionalNullableProducer().get().get().get().get()).isNull();
-  }
-
-  @Test
-  public void optionalNullableProduced() throws Exception {
-    assertThat(component.optionalNullableProduced().get().get().get()).isNull();
-  }
-}
diff --git a/javatests/dagger/functional/producers/provisions/Provisions.java b/javatests/dagger/functional/producers/provisions/Provisions.java
deleted file mode 100644
index 16f3337..0000000
--- a/javatests/dagger/functional/producers/provisions/Provisions.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.provisions;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.Producer;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-
-/** Tests for requesting provisions from producers. */
-final class Provisions {
-  static final class InjectedClass {
-    @Inject InjectedClass() {}
-  }
-
-  static final class WrappedProducer<T> {
-    final Producer<T> producer;
-
-    WrappedProducer(Producer<T> producer) {
-      this.producer = producer;
-    }
-  }
-
-  static final class Output {
-    final Producer<InjectedClass> injectedClass1;
-    final Producer<InjectedClass> injectedClass2;
-
-    Output(Producer<InjectedClass> injectedClass1, Producer<InjectedClass> injectedClass2) {
-      this.injectedClass1 = injectedClass1;
-      this.injectedClass2 = injectedClass2;
-    }
-  }
-
-  @Qualifier @interface First {}
-  @Qualifier @interface Second {}
-
-  @ProducerModule
-  static final class TestModule {
-    @Produces @First static WrappedProducer<InjectedClass> firstProducer(
-        Producer<InjectedClass> injectedClass) {
-      return new WrappedProducer<>(injectedClass);
-    }
-
-    @Produces @Second static WrappedProducer<InjectedClass> secondProducer(
-        Producer<InjectedClass> injectedClass) {
-      return new WrappedProducer<>(injectedClass);
-    }
-
-    @Produces static Output output(
-        @First WrappedProducer<InjectedClass> producer1,
-        @Second WrappedProducer<InjectedClass> producer2) {
-      return new Output(producer1.producer, producer2.producer);
-    }
-  }
-
-  @ProductionComponent(modules = {ExecutorModule.class, TestModule.class})
-  interface TestComponent {
-    ListenableFuture<Output> output();
-  }
-
-  private Provisions() {}
-}
diff --git a/javatests/dagger/functional/producers/provisions/ProvisionsTest.java b/javatests/dagger/functional/producers/provisions/ProvisionsTest.java
deleted file mode 100644
index 47ed2a2..0000000
--- a/javatests/dagger/functional/producers/provisions/ProvisionsTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.provisions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.provisions.Provisions.Output;
-import dagger.functional.producers.provisions.Provisions.TestComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ProvisionsTest {
-
-  @Test
-  public void provisionsOnlyAreHeldInOneProducer() throws Exception {
-    TestComponent component = DaggerProvisions_TestComponent.create();
-    Output output = component.output().get();
-    assertThat(output.injectedClass1).isSameInstanceAs(output.injectedClass2);
-  }
-}
diff --git a/javatests/dagger/functional/producers/scope/ScopeTest.java b/javatests/dagger/functional/producers/scope/ScopeTest.java
deleted file mode 100644
index 9cfd2c2..0000000
--- a/javatests/dagger/functional/producers/scope/ScopeTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.scope;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ScopeTest {
-
-  @Test
-  public void scope() throws Exception {
-    SetComponent component = DaggerSetComponent.create();
-    assertThat(component.set().get()).hasSize(1);
-    assertThat(component.scopedObject()).isSameInstanceAs(component.scopedObject());
-  }
-}
diff --git a/javatests/dagger/functional/producers/scope/ScopedModule.java b/javatests/dagger/functional/producers/scope/ScopedModule.java
deleted file mode 100644
index eec300b..0000000
--- a/javatests/dagger/functional/producers/scope/ScopedModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.producers.ProductionScope;
-
-@Module
-final class ScopedModule {
-  @Provides
-  @ProductionScope
-  static Object newScopedObject() {
-    return new Object();
-  }
-}
diff --git a/javatests/dagger/functional/producers/scope/ScopedObject.java b/javatests/dagger/functional/producers/scope/ScopedObject.java
deleted file mode 100644
index 07eebd9..0000000
--- a/javatests/dagger/functional/producers/scope/ScopedObject.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.scope;
-
-import dagger.producers.ProductionScope;
-import javax.inject.Inject;
-
-@ProductionScope
-final class ScopedObject {
-  @Inject
-  ScopedObject() {}
-}
diff --git a/javatests/dagger/functional/producers/scope/SetComponent.java b/javatests/dagger/functional/producers/scope/SetComponent.java
deleted file mode 100644
index 8400b70..0000000
--- a/javatests/dagger/functional/producers/scope/SetComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.scope;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProductionComponent;
-import java.util.Set;
-
-@ProductionComponent(modules = {ExecutorModule.class, ScopedModule.class, SetProducerModule.class})
-interface SetComponent {
-  ScopedObject scopedObject();
-
-  ListenableFuture<Set<Object>> set();
-}
diff --git a/javatests/dagger/functional/producers/scope/SetProducerModule.java b/javatests/dagger/functional/producers/scope/SetProducerModule.java
deleted file mode 100644
index f88c91b..0000000
--- a/javatests/dagger/functional/producers/scope/SetProducerModule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.scope;
-
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-/**
- * A module that provides two entries into a set; but since the inputs are scoped, the set should
- * only have one value.
- */
-@ProducerModule
-final class SetProducerModule {
-  @Produces
-  @IntoSet
-  static Object setValue1(Object value) {
-    return value;
-  }
-
-  @Produces
-  @IntoSet
-  static Object setValue2(Object value) {
-    return value;
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/ModuleSubcomponentsInterop.java b/javatests/dagger/functional/producers/subcomponent/ModuleSubcomponentsInterop.java
deleted file mode 100644
index 673be2b..0000000
--- a/javatests/dagger/functional/producers/subcomponent/ModuleSubcomponentsInterop.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-
-final class ModuleSubcomponentsInterop {
-  @Component(modules = ProvisionTestModule.class)
-  interface ProvisionParent {
-    ProductionChild.Builder productionChild();
-  }
-
-  @Module(subcomponents = ProductionChild.class)
-  static class ProvisionTestModule {}
-
-  @ProductionSubcomponent
-  interface ProductionChild {
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      ProductionChild build();
-    }
-  }
-
-  @ProductionComponent(modules = ProductionTestModule.class)
-  interface ProductionParent {
-    ProvisionChild.Builder provisionBuilder();
-  }
-
-  @ProducerModule(subcomponents = ProvisionChild.class)
-  static class ProductionTestModule {}
-
-  @Subcomponent
-  interface ProvisionChild {
-    @Subcomponent.Builder
-    interface Builder {
-      ProvisionChild build();
-    }
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponentTest.java b/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponentTest.java
deleted file mode 100644
index 482991d..0000000
--- a/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponentTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.subcomponent.MultiPackageSubcomponents.ParentComponent;
-import dagger.functional.producers.subcomponent.sub.ChildComponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class MultiPackageSubcomponentTest {
-
-  @Test
-  public void childComponent() throws Exception {
-    ParentComponent parent = DaggerMultiPackageSubcomponents_ParentComponent.create();
-    ChildComponent child = parent.childComponentBuilder().build();
-    assertThat(child.str().get()).isEqualTo("Hello, World 42");
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponents.java b/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponents.java
deleted file mode 100644
index 953bfff..0000000
--- a/javatests/dagger/functional/producers/subcomponent/MultiPackageSubcomponents.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.functional.producers.subcomponent.sub.ChildComponent;
-
-final class MultiPackageSubcomponents {
-  @Component(modules = IntModule.class)
-  interface ParentComponent {
-    ChildComponent.Builder childComponentBuilder();
-  }
-
-  @Module
-  static final class IntModule {
-    @Provides
-    static int i() {
-      return 42;
-    }
-  }
-
-  private MultiPackageSubcomponents() {}
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/ProducerModuleWithSubcomponentsTest.java b/javatests/dagger/functional/producers/subcomponent/ProducerModuleWithSubcomponentsTest.java
deleted file mode 100644
index 7568071..0000000
--- a/javatests/dagger/functional/producers/subcomponent/ProducerModuleWithSubcomponentsTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.subcomponent.UsesProducerModuleSubcomponents.ParentIncludesProductionSubcomponentTransitively;
-import dagger.producers.ProducerModule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link ProducerModule#subcomponents()}. */
-@RunWith(JUnit4.class)
-public class ProducerModuleWithSubcomponentsTest {
-
-  @Test
-  public void subcomponentFromModules() throws Exception {
-    UsesProducerModuleSubcomponents parent = DaggerUsesProducerModuleSubcomponents.create();
-    assertThat(parent.strings().get()).containsExactly("from parent");
-    assertThat(parent.stringsFromChild().get()).containsExactly("from parent", "from child");
-  }
-
-  @Test
-  public void subcomponentFromModules_transitively() throws Exception {
-    ParentIncludesProductionSubcomponentTransitively parent =
-        DaggerUsesProducerModuleSubcomponents_ParentIncludesProductionSubcomponentTransitively
-            .create();
-    assertThat(parent.strings().get()).containsExactly("from parent");
-    assertThat(parent.stringsFromChild().get()).containsExactly("from parent", "from child");
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/ProductionSubcomponentFromModuleAndFactoryMethod.java b/javatests/dagger/functional/producers/subcomponent/ProductionSubcomponentFromModuleAndFactoryMethod.java
deleted file mode 100644
index 1286247..0000000
--- a/javatests/dagger/functional/producers/subcomponent/ProductionSubcomponentFromModuleAndFactoryMethod.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-
-/**
- * Tests for {@link Subcomponent}s which are defined with {@link Module#subcomponents()} and are
- * also requested as component factory methods.
- */
-public class ProductionSubcomponentFromModuleAndFactoryMethod {
-  @ProductionSubcomponent
-  interface Sub {
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      Sub sub();
-    }
-  }
-
-  @ProducerModule(subcomponents = Sub.class)
-  static class ModuleWithSubcomponent {}
-
-  @ProductionComponent(modules = {ModuleWithSubcomponent.class, ExecutorModule.class})
-  interface ExposesBuilder {
-    Sub.Builder subcomponentBuilder();
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/SubcomponentWithBoundExecutorTest.java b/javatests/dagger/functional/producers/subcomponent/SubcomponentWithBoundExecutorTest.java
deleted file mode 100644
index 6d176d7..0000000
--- a/javatests/dagger/functional/producers/subcomponent/SubcomponentWithBoundExecutorTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.ChildComponent;
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.ExecutorModule;
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.GrandchildComponent;
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.GrandchildComponentWithoutBuilder;
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.ParentComponent;
-import dagger.functional.producers.subcomponent.SubcomponentsWithBoundExecutor.ParentProductionComponent;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class SubcomponentWithBoundExecutorTest {
-  private ParentComponent parentComponent;
-  private ParentProductionComponent parentProductionComponent;
-  private final AtomicInteger executorConstructionCount = new AtomicInteger();
-  private final AtomicInteger executionCount = new AtomicInteger();
-
-  @Before
-  public void setUp() {
-    parentComponent =
-        DaggerSubcomponentsWithBoundExecutor_ParentComponent.builder()
-            .executorModule(new ExecutorModule(executorConstructionCount, executionCount))
-            .build();
-    parentProductionComponent =
-        DaggerSubcomponentsWithBoundExecutor_ParentProductionComponent.builder()
-            .executorModule(new ExecutorModule(executorConstructionCount, executionCount))
-            .build();
-  }
-
-  @Test
-  public void topLevelComponent_child() throws Exception {
-    ChildComponent child = parentComponent.newChildComponentBuilder().build();
-    assertThat(child.fromChild().get()).isEqualTo("child:parent");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(1);
-  }
-
-  @Test
-  public void topLevelComponent_injectsChildBuilder() throws Exception {
-    ChildComponent child = parentComponent.injectsChildBuilder().childBuilder().build();
-    assertThat(child.fromChild().get()).isEqualTo("child:parent");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(1);
-  }
-
-  @Test
-  public void topLevelComponent_grandchild() throws Exception {
-    ChildComponent child = parentComponent.newChildComponentBuilder().build();
-    GrandchildComponent grandchild = child.newGrandchildComponentBuilder().build();
-    assertThat(grandchild.fromGrandchild().get()).isEqualTo("grandchild:child:parent");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(2);
-  }
-
-  @Test
-  public void topLevelComponent_grandchildWithoutBuilder() throws Exception {
-    ChildComponent child = parentComponent.newChildComponentBuilder().build();
-    GrandchildComponentWithoutBuilder grandchild = child.newGrandchildComponent();
-    assertThat(grandchild.fromGrandchild().get()).isEqualTo("grandchild:child:parent");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(2);
-  }
-
-  @Test
-  public void topLevelProductionComponent_child() throws Exception {
-    ChildComponent child = parentProductionComponent.newChildComponentBuilder().build();
-    assertThat(child.fromChild().get()).isEqualTo("child:parentproduction");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(2);
-  }
-
-  @Test
-  public void topLevelProductionComponent_grandchild() throws Exception {
-    ChildComponent child = parentProductionComponent.newChildComponentBuilder().build();
-    GrandchildComponent grandchild = child.newGrandchildComponentBuilder().build();
-    assertThat(grandchild.fromGrandchild().get()).isEqualTo("grandchild:child:parentproduction");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(3);
-  }
-
-  @Test
-  public void topLevelProductionComponent_grandchildWithoutBuilder() throws Exception {
-    ChildComponent child = parentProductionComponent.newChildComponentBuilder().build();
-    GrandchildComponentWithoutBuilder grandchild = child.newGrandchildComponent();
-    assertThat(grandchild.fromGrandchild().get()).isEqualTo("grandchild:child:parentproduction");
-    assertThat(executorConstructionCount.get()).isEqualTo(1);
-    assertThat(executionCount.get()).isEqualTo(3);
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java b/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java
deleted file mode 100644
index f7059c7..0000000
--- a/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.Production;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-
-final class SubcomponentsWithBoundExecutor {
-  @Qualifier
-  @interface FromParent {}
-
-  @Qualifier
-  @interface FromChild {}
-
-  @Qualifier
-  @interface FromGrandchild {}
-
-  static final class CountingExecutor implements Executor {
-    private final AtomicInteger executionCount;
-
-    CountingExecutor(AtomicInteger executionCount) {
-      this.executionCount = executionCount;
-    }
-
-    @Override
-    public void execute(Runnable runnable) {
-      executionCount.incrementAndGet();
-      runnable.run();
-    }
-  }
-
-  @Module
-  static final class ExecutorModule {
-    private final AtomicInteger constructionCount;
-    private final AtomicInteger executionCount;
-
-    ExecutorModule(AtomicInteger constructionCount, AtomicInteger executionCount) {
-      this.constructionCount = constructionCount;
-      this.executionCount = executionCount;
-    }
-
-    @Provides
-    @Production
-    Executor executor() {
-      constructionCount.incrementAndGet();
-      return new CountingExecutor(executionCount);
-    }
-  }
-
-  @Module
-  static final class ParentModule {
-    @Provides
-    @FromParent
-    static String fromParent() {
-      return "parent";
-    }
-  }
-
-  @Component(modules = {ParentModule.class, ExecutorModule.class})
-  interface ParentComponent {
-    InjectsChildBuilder injectsChildBuilder();
-
-    ChildComponent.Builder newChildComponentBuilder();
-  }
-
-  @ProducerModule
-  static final class ParentProducerModule {
-    @Produces
-    @FromParent
-    static String fromParent() {
-      return "parentproduction";
-    }
-  }
-
-  @ProductionComponent(modules = {ParentProducerModule.class, ExecutorModule.class})
-  interface ParentProductionComponent {
-    ChildComponent.Builder newChildComponentBuilder();
-
-    @ProductionComponent.Builder
-    interface Builder {
-      Builder executorModule(ExecutorModule executorModule);
-
-      ParentProductionComponent build();
-    }
-  }
-
-  @ProducerModule
-  static final class ChildProducerModule {
-    @Produces
-    @FromChild
-    static String fromChild(@FromParent String fromParent) {
-      return "child:" + fromParent;
-    }
-  }
-
-  @ProductionSubcomponent(modules = ChildProducerModule.class)
-  interface ChildComponent {
-    @FromChild
-    ListenableFuture<String> fromChild();
-
-    GrandchildComponent.Builder newGrandchildComponentBuilder();
-    GrandchildComponentWithoutBuilder newGrandchildComponent();
-
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      ChildComponent build();
-    }
-  }
-
-  static final class InjectsChildBuilder {
-    private final Provider<ChildComponent.Builder> childBuilder;
-
-    @Inject
-    InjectsChildBuilder(Provider<ChildComponent.Builder> childBuilder) {
-      this.childBuilder = childBuilder;
-    }
-
-    ChildComponent.Builder childBuilder() {
-      return childBuilder.get();
-    }
-  }
-
-  @ProducerModule
-  static final class GrandchildProducerModule {
-    @Produces
-    @FromGrandchild
-    static String fromGranchild(@FromChild String fromChild) {
-      return "grandchild:" + fromChild;
-    }
-  }
-
-  @ProductionSubcomponent(modules = GrandchildProducerModule.class)
-  interface GrandchildComponent {
-    @FromGrandchild
-    ListenableFuture<String> fromGrandchild();
-
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      GrandchildComponent build();
-    }
-  }
-
-  @ProductionSubcomponent(modules = GrandchildProducerModule.class)
-  interface GrandchildComponentWithoutBuilder {
-    @FromGrandchild
-    ListenableFuture<String> fromGrandchild();
-  }
-
-  private SubcomponentsWithBoundExecutor() {}
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/UsesProducerModuleSubcomponents.java b/javatests/dagger/functional/producers/subcomponent/UsesProducerModuleSubcomponents.java
deleted file mode 100644
index 31253cc..0000000
--- a/javatests/dagger/functional/producers/subcomponent/UsesProducerModuleSubcomponents.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.util.Set;
-import javax.inject.Qualifier;
-
-/** Supporting types for {@code ProducerModuleWithSubcomponentsTest}. */
-@ProductionComponent(
-  modules = UsesProducerModuleSubcomponents.ProducerModuleWithSubcomponents.class
-)
-public interface UsesProducerModuleSubcomponents {
-
-  ListenableFuture<Set<String>> strings();
-
-  @FromChild
-  ListenableFuture<Set<String>> stringsFromChild();
-
-  @ProducerModule(
-    subcomponents = Child.class,
-    includes = {AlsoIncludesSubcomponents.class, ExecutorModule.class}
-  )
-  class ProducerModuleWithSubcomponents {
-    @Produces
-    @IntoSet
-    static String produceStringInParent() {
-      return "from parent";
-    }
-
-    @Produces
-    @FromChild
-    static Set<String> stringsFromChild(Child.Builder childBuilder) throws Exception {
-      return childBuilder.build().strings().get();
-    }
-  }
-
-  @ProducerModule(subcomponents = Child.class)
-  class AlsoIncludesSubcomponents {}
-
-  @ProductionSubcomponent(modules = ChildModule.class)
-  interface Child {
-    ListenableFuture<Set<String>> strings();
-
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      Child build();
-    }
-  }
-
-  @ProducerModule
-  class ChildModule {
-    @Produces
-    @IntoSet
-    static String produceStringInChild() {
-      return "from child";
-    }
-  }
-
-  @Qualifier
-  @interface FromChild {}
-
-  @ProducerModule(includes = ProducerModuleWithSubcomponents.class)
-  class OnlyIncludesProducerModuleWithSubcomponents {}
-
-  @ProductionComponent(modules = OnlyIncludesProducerModuleWithSubcomponents.class)
-  interface ParentIncludesProductionSubcomponentTransitively
-      extends UsesProducerModuleSubcomponents {}
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/pruning/ParentDoesntUseProductionSubcomponent.java b/javatests/dagger/functional/producers/subcomponent/pruning/ParentDoesntUseProductionSubcomponent.java
deleted file mode 100644
index bf931c1..0000000
--- a/javatests/dagger/functional/producers/subcomponent/pruning/ParentDoesntUseProductionSubcomponent.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent.pruning;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import dagger.producers.ProductionComponent;
-import dagger.producers.ProductionSubcomponent;
-import java.util.Set;
-import javax.inject.Qualifier;
-
-/**
- * Supporting types for {@code ProductionSubcomponentOnlyRequestedBySiblingTest}. {@link ChildA} is
- * a direct child of the top level component, but is only requested within its sibling, not directly
- * from its parent.
- */
-@ProductionComponent(
-  modules = {
-    ParentDoesntUseProductionSubcomponent.ParentModule.class,
-    dagger.functional.producers.ExecutorModule.class
-  }
-)
-interface ParentDoesntUseProductionSubcomponent {
-
-  ChildB.Builder childBBuilder();
-
-  @ProductionSubcomponent(modules = ChildAModule.class)
-  interface ChildA {
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      ChildA build();
-    }
-
-    ListenableFuture<Set<Class<?>>> componentHierarchy();
-  }
-
-  @ProductionSubcomponent(modules = ChildBModule.class)
-  interface ChildB {
-    @ProductionSubcomponent.Builder
-    interface Builder {
-      ChildB build();
-    }
-
-    ListenableFuture<Set<Class<?>>> componentHierarchy();
-
-    @FromChildA
-    ListenableFuture<Set<Class<?>>> componentHierarchyFromChildA();
-  }
-
-  @ProducerModule(subcomponents = {ChildA.class, ChildB.class})
-  class ParentModule {
-    @Produces
-    @IntoSet
-    static Class<?> produceComponentType() {
-      return ParentDoesntUseProductionSubcomponent.class;
-    }
-  }
-
-  @ProducerModule
-  class ChildAModule {
-    @Produces
-    @IntoSet
-    static Class<?> produceComponentType() {
-      return ChildA.class;
-    }
-  }
-
-  @ProducerModule
-  class ChildBModule {
-    @Produces
-    @IntoSet
-    static Class<?> produceComponentType() {
-      return ChildB.class;
-    }
-
-    @Produces
-    @FromChildA
-    Set<Class<?>> fromChildA(ChildA.Builder childABuilder) throws Exception {
-      return childABuilder.build().componentHierarchy().get();
-    }
-  }
-
-  @Qualifier
-  @interface FromChildA {}
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/pruning/ProductionSubcomponentOnlyRequestedBySiblingTest.java b/javatests/dagger/functional/producers/subcomponent/pruning/ProductionSubcomponentOnlyRequestedBySiblingTest.java
deleted file mode 100644
index d178061..0000000
--- a/javatests/dagger/functional/producers/subcomponent/pruning/ProductionSubcomponentOnlyRequestedBySiblingTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent.pruning;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.functional.producers.subcomponent.pruning.ParentDoesntUseProductionSubcomponent.ChildA;
-import dagger.functional.producers.subcomponent.pruning.ParentDoesntUseProductionSubcomponent.ChildB;
-import dagger.producers.ProducerModule;
-import dagger.producers.ProductionSubcomponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link ProductionSubcomponent}s which are included with {@link
- * ProducerModule#subcomponents()} but not used directly within the component which adds them.
- *
- * <p>This tests to make sure that while resolving one subcomponent (A), another subcomponent (B)
- * can be requested if they have a shared ancestor component. If that shared ancestor did not
- * resolve B directly via any of its entry points, B will still be generated since it is requested
- * by a descendant.
- */
-@RunWith(JUnit4.class)
-public class ProductionSubcomponentOnlyRequestedBySiblingTest {
-  @Test
-  public void subcomponentAddedInParent_onlyUsedInSibling() throws Exception {
-    ParentDoesntUseProductionSubcomponent parent =
-        DaggerParentDoesntUseProductionSubcomponent.create();
-    ChildB childB = parent.childBBuilder().build();
-    assertThat(childB.componentHierarchy().get())
-        .containsExactly(ParentDoesntUseProductionSubcomponent.class, ChildB.class);
-    assertThat(childB.componentHierarchyFromChildA().get())
-        .containsExactly(ParentDoesntUseProductionSubcomponent.class, ChildA.class);
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/sub/ChildComponent.java b/javatests/dagger/functional/producers/subcomponent/sub/ChildComponent.java
deleted file mode 100644
index 4dfb112..0000000
--- a/javatests/dagger/functional/producers/subcomponent/sub/ChildComponent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent.sub;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.functional.producers.ExecutorModule;
-import dagger.producers.ProductionSubcomponent;
-
-@ProductionSubcomponent(modules = {ExecutorModule.class, ChildModule.class})
-public interface ChildComponent {
-  ListenableFuture<String> str();
-
-  @ProductionSubcomponent.Builder
-  interface Builder {
-    ChildComponent build();
-  }
-}
diff --git a/javatests/dagger/functional/producers/subcomponent/sub/ChildModule.java b/javatests/dagger/functional/producers/subcomponent/sub/ChildModule.java
deleted file mode 100644
index 8994a8a..0000000
--- a/javatests/dagger/functional/producers/subcomponent/sub/ChildModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.producers.subcomponent.sub;
-
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-
-@ProducerModule
-final class ChildModule {
-  @Produces
-  static String str(int n) {
-    return "Hello, World " + n;
-  }
-}
diff --git a/javatests/dagger/functional/rawtypes/RawTypesComponent.java b/javatests/dagger/functional/rawtypes/RawTypesComponent.java
deleted file mode 100644
index e2c69c2..0000000
--- a/javatests/dagger/functional/rawtypes/RawTypesComponent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.rawtypes;
-
-import dagger.Component;
-import java.util.Map;
-import java.util.Set;
-
-@SuppressWarnings("rawtypes")
-@Component(modules = RawtypesModule.class)
-interface RawTypesComponent {
-  Set rawSet();
-  Map rawMap();
-}
diff --git a/javatests/dagger/functional/rawtypes/RawtypesModule.java b/javatests/dagger/functional/rawtypes/RawtypesModule.java
deleted file mode 100644
index 3bf5f59..0000000
--- a/javatests/dagger/functional/rawtypes/RawtypesModule.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.rawtypes;
-
-import dagger.Module;
-import dagger.Provides;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-@SuppressWarnings("rawtypes")
-@Module
-abstract class RawtypesModule {
-  @Provides
-  static Map rawMap() {
-    return new HashMap();
-  }
-
-  @Provides
-  static Set rawSet() {
-    return new HashSet();
-  }
-}
diff --git a/javatests/dagger/functional/scope/BlueModule.java b/javatests/dagger/functional/scope/BlueModule.java
deleted file mode 100644
index e04bc7a..0000000
--- a/javatests/dagger/functional/scope/BlueModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class BlueModule {
-  @Provides
-  @IntoSet
-  @BlueScope
-  static Object blue() {
-    return new Object();
-  }
-}
diff --git a/javatests/dagger/functional/scope/BlueScope.java b/javatests/dagger/functional/scope/BlueScope.java
deleted file mode 100644
index ecd0da5..0000000
--- a/javatests/dagger/functional/scope/BlueScope.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-@Documented
-@Retention(RUNTIME)
-@Scope
-@interface BlueScope {}
diff --git a/javatests/dagger/functional/scope/GreenModule.java b/javatests/dagger/functional/scope/GreenModule.java
deleted file mode 100644
index 3f9248f..0000000
--- a/javatests/dagger/functional/scope/GreenModule.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class GreenModule  {
-  @Provides
-  @IntoSet
-  @GreenScope
-  static Object green() {
-    return new Object();
-  }
-}
diff --git a/javatests/dagger/functional/scope/GreenScope.java b/javatests/dagger/functional/scope/GreenScope.java
deleted file mode 100644
index 92bcc62..0000000
--- a/javatests/dagger/functional/scope/GreenScope.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Scope;
-
-@Documented
-@Retention(RUNTIME)
-@Scope
-@interface GreenScope {}
diff --git a/javatests/dagger/functional/scope/ScopeTest.java b/javatests/dagger/functional/scope/ScopeTest.java
deleted file mode 100644
index 40c1fa9..0000000
--- a/javatests/dagger/functional/scope/ScopeTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ScopeTest {
-
-  @Test
-  public void testScope() {
-    ScopedComponent component = DaggerScopedComponent.create();
-    assertThat(component.set()).hasSize(4);
-    assertThat(component.set()).isEqualTo(component.set());
-  }
-}
diff --git a/javatests/dagger/functional/scope/ScopedComponent.java b/javatests/dagger/functional/scope/ScopedComponent.java
deleted file mode 100644
index fa9b0da..0000000
--- a/javatests/dagger/functional/scope/ScopedComponent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import dagger.Component;
-import java.util.Set;
-
-@BlueScope
-@GreenScope
-@Component(modules = {BlueModule.class, GreenModule.class, TurquoiseModule.class})
-interface ScopedComponent {
-  Set<Object> set();
-}
diff --git a/javatests/dagger/functional/scope/TurquoiseModule.java b/javatests/dagger/functional/scope/TurquoiseModule.java
deleted file mode 100644
index 780ecb2..0000000
--- a/javatests/dagger/functional/scope/TurquoiseModule.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class TurquoiseModule {
-  @Provides
-  @IntoSet
-  @BlueScope
-  static Object blue() {
-    return new Object();
-  }
-
-  @Provides
-  @IntoSet
-  @GreenScope
-  static Object green() {
-    return new Object();
-  }
-}
diff --git a/javatests/dagger/functional/spi/BUILD b/javatests/dagger/functional/spi/BUILD
deleted file mode 100644
index fffaddb..0000000
--- a/javatests/dagger/functional/spi/BUILD
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Functional tests for the experimental Dagger SPI
-
-package(default_visibility = ["//:src"])
-
-load("//:test_defs.bzl", "GenJavaTests")
-
-java_plugin(
-    name = "test_plugin",
-    srcs = ["TestPlugin.java"],
-    deps = [
-        "//java/dagger/model",
-        "//java/dagger/spi",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-    ],
-)
-
-java_library(
-    name = "test_lib",
-    exported_plugins = [":test_plugin"],
-)
-
-GenJavaTests(
-    name = "tests",
-    srcs = glob(
-        ["*.java"],
-        exclude = ["TestPlugin.java"],
-    ),
-    functional = 0,
-    test_only_deps = [
-        "@google_bazel_common//third_party/java/truth",
-        "@google_bazel_common//third_party/java/junit",
-    ],
-    deps = [
-        ":test_lib",
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/guava",
-    ],
-)
diff --git a/javatests/dagger/functional/spi/SpiTest.java b/javatests/dagger/functional/spi/SpiTest.java
deleted file mode 100644
index 05495e5..0000000
--- a/javatests/dagger/functional/spi/SpiTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.spi;
-
-import static com.google.common.io.Resources.getResource;
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SpiTest {
-
-  @Component(modules = M.class)
-  interface C {
-    String string();
-  }
-
-  @Module
-  abstract static class M {
-    @Provides
-    static String string() {
-      return "string";
-    }
-  }
-
-  @Test
-  public void testPluginRuns() throws IOException {
-    Properties properties = new Properties();
-    try (InputStream stream = getResource(SpiTest.class, "SpiTest_C.properties").openStream()) {
-      properties.load(stream);
-    }
-    assertThat(properties).containsEntry("component[0]", C.class.getCanonicalName());
-  }
-}
diff --git a/javatests/dagger/functional/spi/TestPlugin.java b/javatests/dagger/functional/spi/TestPlugin.java
deleted file mode 100644
index 360bc20..0000000
--- a/javatests/dagger/functional/spi/TestPlugin.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 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.functional.spi;
-
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
-import com.google.auto.service.AutoService;
-import com.google.common.base.Joiner;
-import com.squareup.javapoet.ClassName;
-import dagger.model.BindingGraph;
-import dagger.model.BindingGraph.ComponentNode;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.io.Writer;
-import java.util.Properties;
-import javax.annotation.processing.Filer;
-
-@AutoService(BindingGraphPlugin.class)
-public final class TestPlugin implements BindingGraphPlugin {
-  private Filer filer;
-
-  @Override
-  public void initFiler(Filer filer) {
-    this.filer = filer;
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    Properties properties = new Properties();
-    int i = 0;
-    for (ComponentNode node : bindingGraph.componentNodes()) {
-      properties.setProperty(
-          String.format("component[%s]", i++), node.componentPath().toString());
-    }
-
-    write(bindingGraph, properties);
-  }
-
-  private void write(BindingGraph bindingGraph, Properties properties) {
-    ClassName rootComponentName =
-        ClassName.get(bindingGraph.rootComponentNode().componentPath().currentComponent());
-    try (Writer writer =
-        filer
-            .createResource(
-                CLASS_OUTPUT,
-                rootComponentName.packageName(),
-                Joiner.on('_').join(rootComponentName.simpleNames()) + ".properties")
-            .openWriter()) {
-      properties.store(writer, "");
-    } catch (IOException e) {
-      throw new UncheckedIOException(e);
-    }
-  }
-}
diff --git a/javatests/dagger/functional/staticprovides/AllStaticModule.java b/javatests/dagger/functional/staticprovides/AllStaticModule.java
deleted file mode 100644
index fff63ee..0000000
--- a/javatests/dagger/functional/staticprovides/AllStaticModule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.staticprovides;
-
-import static java.util.Collections.emptySet;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
-import java.util.Set;
-
-@Module
-final class AllStaticModule {
-  @Provides
-  @IntoSet
-  static String contributeString() {
-    return AllStaticModule.class + ".contributeString";
-  }
-
-  @Provides
-  @ElementsIntoSet
-  static Set<Integer> contibuteEmptyIntegerSet() {
-    return emptySet();
-  }
-}
diff --git a/javatests/dagger/functional/staticprovides/SomeStaticModule.java b/javatests/dagger/functional/staticprovides/SomeStaticModule.java
deleted file mode 100644
index ab65b58..0000000
--- a/javatests/dagger/functional/staticprovides/SomeStaticModule.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.staticprovides;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class SomeStaticModule {
-  @Provides
-  @IntoSet
-  static String contributeStringFromAStaticMethod() {
-    return SomeStaticModule.class + ".contributeStringFromAStaticMethod";
-  }
-
-  @Provides
-  @IntoSet
-  static String contributeStringFromAnInstanceMethod() {
-    return SomeStaticModule.class + ".contributeStringFromAnInstanceMethod";
-  }
-}
diff --git a/javatests/dagger/functional/staticprovides/StaticProvidesTest.java b/javatests/dagger/functional/staticprovides/StaticProvidesTest.java
deleted file mode 100644
index 9d9952a..0000000
--- a/javatests/dagger/functional/staticprovides/StaticProvidesTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.staticprovides;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.google.common.collect.ImmutableSet;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class StaticProvidesTest {
-  @Parameters
-  public static Collection<Object[]> components() {
-    return Arrays.asList(new Object[][] {
-        {DaggerStaticTestComponent.create()},
-        {DaggerStaticTestComponentWithBuilder.builder().build()},
-        {DaggerStaticTestComponentWithBuilder.builder()
-          .allStaticModule(new AllStaticModule())
-          .someStaticModule(new SomeStaticModule())
-          .build()}});
-  }
-
-  @Parameter
-  public StaticTestComponent component;
-
-  @Test public void setMultibinding() {
-    assertThat(component.getMultiboundStrings()).isEqualTo(ImmutableSet.of(
-        AllStaticModule.class + ".contributeString",
-        SomeStaticModule.class + ".contributeStringFromAStaticMethod",
-        SomeStaticModule.class + ".contributeStringFromAnInstanceMethod"));
-  }
-
-  @Test public void allStaticProvidesModules_noFieldInComponentBuilder() {
-    for (Field field : DaggerStaticTestComponent.Builder.class.getDeclaredFields()) {
-      assertWithMessage(field.getName())
-          .that(field.getType()).isNotEqualTo(AllStaticModule.class);
-    }
-  }
-
-  @Test public void allStaticProvidesModules_deprecatedMethodInComponentBuilder() {
-    for (Method method : DaggerStaticTestComponent.Builder.class.getDeclaredMethods()) {
-      if (Arrays.asList(method.getParameterTypes()).contains(AllStaticModule.class)) {
-        assertWithMessage(method.getName())
-            .that(method.isAnnotationPresent(Deprecated.class))
-            .isTrue();
-      }
-    }
-  }
-}
diff --git a/javatests/dagger/functional/staticprovides/StaticTestComponent.java b/javatests/dagger/functional/staticprovides/StaticTestComponent.java
deleted file mode 100644
index 4dced91..0000000
--- a/javatests/dagger/functional/staticprovides/StaticTestComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.staticprovides;
-
-import dagger.Component;
-import java.util.Set;
-
-/**
- * A simple component that demonstrates both static and non-static provides methods.
- */
-@Component(modules = {AllStaticModule.class, SomeStaticModule.class})
-interface StaticTestComponent {
-  Set<String> getMultiboundStrings();
-  Set<Integer> getMultiboundIntegers();
-}
diff --git a/javatests/dagger/functional/staticprovides/StaticTestComponentWithBuilder.java b/javatests/dagger/functional/staticprovides/StaticTestComponentWithBuilder.java
deleted file mode 100644
index c6e8f2a..0000000
--- a/javatests/dagger/functional/staticprovides/StaticTestComponentWithBuilder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.staticprovides;
-
-import dagger.Component;
-
-/**
- * A simple component that demonstrates both static and non-static provides methods with a builder.
- */
-@Component(modules = {AllStaticModule.class, SomeStaticModule.class})
-interface StaticTestComponentWithBuilder extends StaticTestComponent {
-  @Component.Builder
-  interface Builder {
-    Builder allStaticModule(AllStaticModule allStaticModule);
-    Builder someStaticModule(SomeStaticModule someStaticModule);
-    StaticTestComponentWithBuilder build();
-  }
-}
diff --git a/javatests/dagger/functional/sub/ContributionsModule.java b/javatests/dagger/functional/sub/ContributionsModule.java
deleted file mode 100644
index 654e8f7..0000000
--- a/javatests/dagger/functional/sub/ContributionsModule.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-@Module
-public final class ContributionsModule {
-  @Provides
-  @IntoSet
-  static int contributeAnInt(@SuppressWarnings("unused") double doubleDependency) {
-    return 1742;
-  }
-
-  @Provides
-  @IntoSet
-  static int contributeAnotherInt() {
-    return 832;
-  }
-
-  @Provides
-  @ElementsIntoSet
-  static Set<Integer> contributeSomeInts() {
-    return Collections.unmodifiableSet(new LinkedHashSet<Integer>(Arrays.asList(-1, -90, -17)));
-  }
-}
diff --git a/javatests/dagger/functional/sub/Exposed.java b/javatests/dagger/functional/sub/Exposed.java
deleted file mode 100644
index 55c2d15..0000000
--- a/javatests/dagger/functional/sub/Exposed.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import dagger.Lazy;
-import dagger.functional.Generic;
-import dagger.functional.Generic2;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-public class Exposed {
-
-  @Inject public PackagePrivate pp2;
-  @Inject public Provider<PackagePrivate> ppp2;
-  @Inject public Lazy<PackagePrivate> lpp2;
-  @Inject public Provider<Lazy<PackagePrivate>> plpp2;
-  @Inject public Generic2<PackagePrivate> gpp2;
-  @Inject public Generic2<PackagePrivateContainer.PublicEnclosed> gppc2;
-  @Inject public Provider<Generic2<PackagePrivate>> pgpp2;
-  @Inject public Lazy<Generic2<PackagePrivate>> lgpp2;
-  @Inject public Provider<Lazy<Generic2<PackagePrivate>>> plgpp2;
-
-  public PackagePrivate pp;
-  public Provider<PackagePrivate> ppp;
-  public Lazy<PackagePrivate> lpp;
-  public Provider<Lazy<PackagePrivate>> plpp;
-  public Generic<PackagePrivate> gpp;
-  public Generic<PackagePrivateContainer.PublicEnclosed> gppc;
-  public Provider<Generic<PackagePrivate>> pgpp;
-  public Lazy<Generic<PackagePrivate>> lgpp;
-  public Provider<Lazy<Generic<PackagePrivate>>> plgpp;
-
-  /** Injects inaccessible dependencies to test casting of these dependency arguments. */
-  @Inject Exposed(
-      PackagePrivate pp,
-      Provider<PackagePrivate> ppp,
-      Lazy<PackagePrivate> lpp,
-      Provider<Lazy<PackagePrivate>> plpp,
-      Generic<PackagePrivate> gpp,
-      Generic<PackagePrivateContainer.PublicEnclosed> gppc,
-      Provider<Generic<PackagePrivate>> pgpp,
-      Lazy<Generic<PackagePrivate>> lgpp,
-      Provider<Lazy<Generic<PackagePrivate>>> plgpp) {
-    this.pp = pp;
-    this.ppp = ppp;
-    this.lpp = lpp;
-    this.plpp = plpp;
-    this.gpp = gpp;
-    this.gppc = gppc;
-    this.pgpp = pgpp;
-    this.lgpp = lgpp;
-    this.plgpp = plgpp;
-  }
-}
diff --git a/javatests/dagger/functional/sub/OtherThing.java b/javatests/dagger/functional/sub/OtherThing.java
deleted file mode 100644
index 9150aab..0000000
--- a/javatests/dagger/functional/sub/OtherThing.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import javax.inject.Inject;
-
-public final class OtherThing {
-  @Inject
-  public OtherThing(@SuppressWarnings("unused") int i) {}
-}
diff --git a/javatests/dagger/functional/sub/PackagePrivate.java b/javatests/dagger/functional/sub/PackagePrivate.java
deleted file mode 100644
index 8220877..0000000
--- a/javatests/dagger/functional/sub/PackagePrivate.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import javax.inject.Inject;
-
-class PackagePrivate {  
-  @Inject PackagePrivate() {}
-}
diff --git a/javatests/dagger/functional/sub/PackagePrivateContainer.java b/javatests/dagger/functional/sub/PackagePrivateContainer.java
deleted file mode 100644
index f1b1033..0000000
--- a/javatests/dagger/functional/sub/PackagePrivateContainer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import javax.inject.Inject;
-
-class PackagePrivateContainer {  
-  public static class PublicEnclosed {
-    @Inject PublicEnclosed() {}
-  }
-}
diff --git a/javatests/dagger/functional/sub/PublicSubclass.java b/javatests/dagger/functional/sub/PublicSubclass.java
deleted file mode 100644
index 2ccd42a..0000000
--- a/javatests/dagger/functional/sub/PublicSubclass.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import dagger.functional.Generic;
-import javax.inject.Inject;
-
-public class PublicSubclass extends Generic<PackagePrivate> {
-  @Inject public PublicSubclass(PackagePrivate pp) {
-    super(pp);
-  }
-}
diff --git a/javatests/dagger/functional/sub/PublicSubclass2.java b/javatests/dagger/functional/sub/PublicSubclass2.java
deleted file mode 100644
index 3d5f429..0000000
--- a/javatests/dagger/functional/sub/PublicSubclass2.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.sub;
-
-import dagger.functional.Generic;
-import javax.inject.Inject;
-
-public class PublicSubclass2 extends Generic<PackagePrivateContainer.PublicEnclosed> {
-  @Inject public PublicSubclass2(PackagePrivateContainer.PublicEnclosed pp) {
-    super(pp);
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/AnInterface.java b/javatests/dagger/functional/subcomponent/AnInterface.java
deleted file mode 100644
index f0d9b4c..0000000
--- a/javatests/dagger/functional/subcomponent/AnInterface.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-interface AnInterface {
-}
diff --git a/javatests/dagger/functional/subcomponent/BoundAsSingleton.java b/javatests/dagger/functional/subcomponent/BoundAsSingleton.java
deleted file mode 100644
index 9d14465..0000000
--- a/javatests/dagger/functional/subcomponent/BoundAsSingleton.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-@Documented
-@Retention(RUNTIME)
-@Qualifier
-@interface BoundAsSingleton {}
diff --git a/javatests/dagger/functional/subcomponent/ChildAbstractClassComponent.java b/javatests/dagger/functional/subcomponent/ChildAbstractClassComponent.java
deleted file mode 100644
index b9bcce2..0000000
--- a/javatests/dagger/functional/subcomponent/ChildAbstractClassComponent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = {ChildModule.class, StaticChildModule.class})
-abstract class ChildAbstractClassComponent implements ChildComponent {
-}
diff --git a/javatests/dagger/functional/subcomponent/ChildComponent.java b/javatests/dagger/functional/subcomponent/ChildComponent.java
deleted file mode 100644
index 6d6fd8b..0000000
--- a/javatests/dagger/functional/subcomponent/ChildComponent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Subcomponent;
-import java.util.Set;
-import javax.inject.Provider;
-
-@Subcomponent(modules = {ChildModule.class, StaticChildModule.class})
-interface ChildComponent {
-  Provider<UnscopedType> getUnscopedTypeProvider();
-
-  RequiresSingletons requiresSingleton();
-
-  Set<Object> objectSet();
-
-  GrandchildComponent newGrandchildComponent();
-  
-  Object object();
-}
diff --git a/javatests/dagger/functional/subcomponent/ChildComponentRequiringModules.java b/javatests/dagger/functional/subcomponent/ChildComponentRequiringModules.java
deleted file mode 100644
index 29b60e2..0000000
--- a/javatests/dagger/functional/subcomponent/ChildComponentRequiringModules.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = {
-    ChildModule.class,
-    ChildModuleWithParameters.class,
-    ChildModuleWithState.class})
-interface ChildComponentRequiringModules {
-  int getInt();
-}
diff --git a/javatests/dagger/functional/subcomponent/ChildModule.java b/javatests/dagger/functional/subcomponent/ChildModule.java
deleted file mode 100644
index f11cefc..0000000
--- a/javatests/dagger/functional/subcomponent/ChildModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class ChildModule {
-  @Provides
-  @IntoSet
-  static Object provideUnscopedObject() {
-    return new Object() {
-      @Override public String toString() {
-        return "unscoped in child";
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/ChildModuleWithParameters.java b/javatests/dagger/functional/subcomponent/ChildModuleWithParameters.java
deleted file mode 100644
index 17f8471..0000000
--- a/javatests/dagger/functional/subcomponent/ChildModuleWithParameters.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Module;
-
-/**
- * This is a module that can't be constructed with a default constructor.
- */
-@Module
-final class ChildModuleWithParameters {
-  public ChildModuleWithParameters(@SuppressWarnings("unused") Object whatever) {}
-}
diff --git a/javatests/dagger/functional/subcomponent/ChildModuleWithState.java b/javatests/dagger/functional/subcomponent/ChildModuleWithState.java
deleted file mode 100644
index 49b266c..0000000
--- a/javatests/dagger/functional/subcomponent/ChildModuleWithState.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * This is a module that can be constructed with a default constructor, but has state, so callers
- * might want to pass a reference anyway.
- */
-@Module
-final class ChildModuleWithState {
-  private int i = 0;
-
-  @Provides int provideInt() {
-    return i++;
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/GenericParentComponent.java b/javatests/dagger/functional/subcomponent/GenericParentComponent.java
deleted file mode 100644
index f49083b..0000000
--- a/javatests/dagger/functional/subcomponent/GenericParentComponent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-interface GenericParentComponent<B> {  
-  B subcomponent();
-}
diff --git a/javatests/dagger/functional/subcomponent/GrandchildComponent.java b/javatests/dagger/functional/subcomponent/GrandchildComponent.java
deleted file mode 100644
index 5a1b772..0000000
--- a/javatests/dagger/functional/subcomponent/GrandchildComponent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Subcomponent;
-import java.util.Set;
-import javax.inject.Provider;
-
-@Subcomponent(modules = GrandchildModule.class)
-interface GrandchildComponent {
-  Provider<UnscopedType> getUnscopedTypeProvider();
-
-  RequiresSingletons requiresSingleton();
-
-  Set<Object> objectSet();
-
-  NeedsAnInterface needsAnInterface();
-}
diff --git a/javatests/dagger/functional/subcomponent/GrandchildModule.java b/javatests/dagger/functional/subcomponent/GrandchildModule.java
deleted file mode 100644
index c61accf..0000000
--- a/javatests/dagger/functional/subcomponent/GrandchildModule.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-abstract class GrandchildModule {
-  @Provides
-  @IntoSet
-  static Object provideUnscopedObject() {
-    return new Object() {
-      @Override public String toString() {
-        return "unscoped in grandchild";
-      }
-    };
-  }
-
-  @Binds
-  abstract AnInterface provideAnInterface(ImplementsAnInterface implementsAnInterface);
-
-  @Provides
-  static NeedsAnInterface provideNeedsAnInterface(AnInterface anInterface) {
-    return new NeedsAnInterface(anInterface);
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/ImplementsAnInterface.java b/javatests/dagger/functional/subcomponent/ImplementsAnInterface.java
deleted file mode 100644
index a07025c..0000000
--- a/javatests/dagger/functional/subcomponent/ImplementsAnInterface.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import javax.inject.Inject;
-
-class ImplementsAnInterface implements AnInterface {
-  @Inject ImplementsAnInterface() {}
-}
-
diff --git a/javatests/dagger/functional/subcomponent/ModuleWithSubcomponentsTest.java b/javatests/dagger/functional/subcomponent/ModuleWithSubcomponentsTest.java
deleted file mode 100644
index 06beae1..0000000
--- a/javatests/dagger/functional/subcomponent/ModuleWithSubcomponentsTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Module;
-import dagger.functional.subcomponent.UsesModuleSubcomponents.ParentIncludesSubcomponentTransitively;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link Module#subcomponents()}. */
-@RunWith(JUnit4.class)
-public class ModuleWithSubcomponentsTest {
-
-  @Test
-  public void subcomponentFromModules() {
-    UsesModuleSubcomponents parent = DaggerUsesModuleSubcomponents.create();
-    assertThat(parent.strings()).containsExactly("from parent");
-    assertThat(parent.usesChild().strings).containsExactly("from parent", "from child");
-  }
-
-  @Test
-  public void subcomponentFromModules_transitively() {
-    ParentIncludesSubcomponentTransitively parent =
-        DaggerUsesModuleSubcomponents_ParentIncludesSubcomponentTransitively.create();
-    assertThat(parent.strings()).containsExactly("from parent");
-    assertThat(parent.usesChild().strings).containsExactly("from parent", "from child");
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/MultibindingSubcomponents.java b/javatests/dagger/functional/subcomponent/MultibindingSubcomponents.java
deleted file mode 100644
index 9959771..0000000
--- a/javatests/dagger/functional/subcomponent/MultibindingSubcomponents.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.IntoSet;
-import dagger.multibindings.StringKey;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import javax.inject.Inject;
-
-final class MultibindingSubcomponents {
-
-  /** Multibindings for this type are bound only in the parent component. */
-  enum BoundInParent {
-    INSTANCE;
-  }
-
-  /** Multibindings for this type are bound only in the child component. */
-  enum BoundInChild {
-    INSTANCE;
-  }
-
-  /** Multibindings for this type are bound in the parent component and the child component. */
-  enum BoundInParentAndChild {
-    IN_PARENT,
-    IN_CHILD;
-  }
-
-  static final class RequiresMultibindings<T> {
-    private final Set<T> set;
-    private final Map<String, T> map;
-
-    @Inject
-    RequiresMultibindings(Set<T> set, Map<String, T> map) {
-      this.set = set;
-      this.map = map;
-    }
-
-    Set<T> set() {
-      return set;
-    }
-
-    Map<String, T> map() {
-      return map;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      return obj instanceof RequiresMultibindings<?>
-          && set.equals(((RequiresMultibindings<?>) obj).set)
-          && map.equals(((RequiresMultibindings<?>) obj).map);
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hash(set, map);
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "%s{set=%s, map=%s}", RequiresMultibindings.class.getSimpleName(), set, map);
-    }
-  }
-
-  @Module
-  abstract static class ParentMultibindingModule {
-
-    @Provides
-    @IntoSet
-    static BoundInParent onlyInParentElement() {
-      return BoundInParent.INSTANCE;
-    }
-
-    @Provides
-    @IntoMap
-    @StringKey("parent key")
-    static BoundInParent onlyInParentEntry() {
-      return BoundInParent.INSTANCE;
-    }
-
-    @Provides
-    @IntoSet
-    static BoundInParentAndChild inParentAndChildElement() {
-      return BoundInParentAndChild.IN_PARENT;
-    }
-
-    @Provides
-    @IntoMap
-    @StringKey("parent key")
-    static BoundInParentAndChild inParentAndChildEntry() {
-      return BoundInParentAndChild.IN_PARENT;
-    }
-
-    /* This is not static because otherwise we have no tests that cover the case where a
-     * subcomponent uses a module instance installed onto a parent component. */
-    @Binds
-    @IntoSet
-    abstract RequiresMultibindings<BoundInParentAndChild>
-        requiresMultibindingsInParentAndChildElement(
-            RequiresMultibindings<BoundInParentAndChild> requiresMultibindingsInParentAndChild);
-  }
-
-  @Module
-  static final class ChildMultibindingModule {
-
-    @Provides
-    @IntoSet
-    static BoundInParentAndChild inParentAndChildElement() {
-      return BoundInParentAndChild.IN_CHILD;
-    }
-
-    @Provides
-    @IntoMap
-    @StringKey("child key")
-    static BoundInParentAndChild inParentAndChildEntry() {
-      return BoundInParentAndChild.IN_CHILD;
-    }
-
-    @Provides
-    @IntoSet
-    static BoundInChild onlyInChildElement() {
-      return BoundInChild.INSTANCE;
-    }
-
-    @Provides
-    @IntoMap
-    @StringKey("child key")
-    static BoundInChild onlyInChildEntry() {
-      return BoundInChild.INSTANCE;
-    }
-  }
-
-  @Module
-  abstract static class ChildMultibindingModuleWithOnlyBindsMultibindings {
-    @Provides
-    static BoundInParentAndChild provideBoundInParentAndChildForBinds() {
-      return BoundInParentAndChild.IN_CHILD;
-    }
-
-    @Binds
-    @IntoSet
-    abstract BoundInParentAndChild bindsLocalContribution(BoundInParentAndChild instance);
-
-    @Binds
-    @IntoMap
-    @StringKey("child key")
-    abstract BoundInParentAndChild inParentAndChildEntry(BoundInParentAndChild instance);
-
-    @Provides
-    static BoundInChild provideBoundInChildForBinds() {
-      return BoundInChild.INSTANCE;
-    }
-
-    @Binds
-    @IntoSet
-    abstract BoundInChild inChild(BoundInChild instance);
-
-    @Binds
-    @IntoMap
-    @StringKey("child key")
-    abstract BoundInChild inChildEntry(BoundInChild instance);
-  }
-
-  interface ProvidesBoundInParent {
-    RequiresMultibindings<BoundInParent> requiresMultibindingsBoundInParent();
-  }
-
-  interface ProvidesBoundInChild {
-    RequiresMultibindings<BoundInChild> requiresMultibindingsBoundInChild();
-  }
-
-  interface ProvidesBoundInParentAndChild {
-    RequiresMultibindings<BoundInParentAndChild> requiresMultibindingsBoundInParentAndChild();
-  }
-
-  interface ProvidesSetOfRequiresMultibindings {
-    Set<RequiresMultibindings<BoundInParentAndChild>> setOfRequiresMultibindingsInParentAndChild();
-  }
-
-  interface ParentWithProvision
-      extends ProvidesBoundInParent, ProvidesBoundInParentAndChild,
-          ProvidesSetOfRequiresMultibindings {}
-
-  interface HasChildWithProvision {
-    ChildWithProvision childWithProvision();
-  }
-
-  interface HasChildWithoutProvision {
-    ChildWithoutProvision childWithoutProvision();
-  }
-
-  @Component(modules = ParentMultibindingModule.class)
-  interface ParentWithoutProvisionHasChildWithoutProvision extends HasChildWithoutProvision {}
-
-  @Component(modules = ParentMultibindingModule.class)
-  interface ParentWithoutProvisionHasChildWithProvision extends HasChildWithProvision {}
-
-  @Component(modules = ParentMultibindingModule.class)
-  interface ParentWithProvisionHasChildWithoutProvision
-      extends ParentWithProvision, HasChildWithoutProvision {}
-
-  @Component(modules = ParentMultibindingModule.class)
-  interface ParentWithProvisionHasChildWithProvision
-      extends ParentWithProvision, HasChildWithProvision {}
-
-  @Subcomponent(modules = ChildMultibindingModule.class)
-  interface ChildWithoutProvision {
-    Grandchild grandchild();
-  }
-
-  @Subcomponent(modules = ChildMultibindingModule.class)
-  interface ChildWithProvision
-      extends ProvidesBoundInParent, ProvidesBoundInParentAndChild, ProvidesBoundInChild,
-          ProvidesSetOfRequiresMultibindings {
-
-    Grandchild grandchild();
-  }
-
-  @Subcomponent
-  interface Grandchild
-      extends ProvidesBoundInParent, ProvidesBoundInParentAndChild, ProvidesBoundInChild,
-          ProvidesSetOfRequiresMultibindings {}
-
-  @Component(modules = ParentMultibindingModule.class)
-  interface ParentWithProvisionHasChildWithBinds extends ParentWithProvision {
-    ChildWithBinds childWithBinds();
-  }
-
-  @Subcomponent(modules = ChildMultibindingModuleWithOnlyBindsMultibindings.class)
-  interface ChildWithBinds extends ChildWithProvision {}
-
-}
diff --git a/javatests/dagger/functional/subcomponent/NeedsAnInterface.java b/javatests/dagger/functional/subcomponent/NeedsAnInterface.java
deleted file mode 100644
index 3efbad7..0000000
--- a/javatests/dagger/functional/subcomponent/NeedsAnInterface.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-class NeedsAnInterface {
-  NeedsAnInterface(@SuppressWarnings("unused") AnInterface anInterface) {}
-}
diff --git a/javatests/dagger/functional/subcomponent/ParentComponent.java b/javatests/dagger/functional/subcomponent/ParentComponent.java
deleted file mode 100644
index 4c0b608..0000000
--- a/javatests/dagger/functional/subcomponent/ParentComponent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Component;
-import dagger.functional.SomeQualifier;
-import javax.inject.Singleton;
-
-@Component(modules = {ParentModule.class, UnresolvableChildComponentModule.class})
-@Singleton
-interface ParentComponent extends ParentGetters {
-  ChildComponent newChildComponent();
-
-  ChildAbstractClassComponent newChildAbstractClassComponent();
-
-  ChildComponentRequiringModules newChildComponentRequiringModules(
-      ChildModuleWithParameters cmwp,
-      ChildModuleWithState childModuleWithState);
-
-  /**
-   * Requests a qualified version of this subcomponent builder, which does not install it as a
-   * subcomponent, but instead, uses the explicit binding of this qualified builder.
-   */
-  @SomeQualifier UnresolvableChildComponent.Builder unresolvableChildComponentBuilder();
-}
diff --git a/javatests/dagger/functional/subcomponent/ParentGetters.java b/javatests/dagger/functional/subcomponent/ParentGetters.java
deleted file mode 100644
index 928bff2..0000000
--- a/javatests/dagger/functional/subcomponent/ParentGetters.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import java.util.Set;
-import javax.inject.Provider;
-
-interface ParentGetters {
-  Provider<UnscopedType> getUnscopedTypeProvider();
-
-  Set<Object> objectSet();
-
-}
diff --git a/javatests/dagger/functional/subcomponent/ParentModule.java b/javatests/dagger/functional/subcomponent/ParentModule.java
deleted file mode 100644
index 8ce4b87..0000000
--- a/javatests/dagger/functional/subcomponent/ParentModule.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-import javax.inject.Singleton;
-
-@Module
-abstract class ParentModule {
-  @Provides
-  @IntoSet
-  static Object provideUnscopedObject() {
-    return new Object() {
-      @Override public String toString() {
-        return "unscoped in parent";
-      }
-    };
-  }
-
-  @Provides
-  @IntoSet
-  @Singleton
-  static Object provideSingletonObject() {
-    return new Object() {
-      @Override public String toString() {
-        return "singleton";
-      }
-    };
-  }
-
-  @Binds
-  @Singleton
-  @BoundAsSingleton
-  abstract UnscopedType provideUnscopedTypeBoundAsSingleton(UnscopedType unscopedType);
-}
diff --git a/javatests/dagger/functional/subcomponent/ParentOfGenericComponent.java b/javatests/dagger/functional/subcomponent/ParentOfGenericComponent.java
deleted file mode 100644
index cc701f4..0000000
--- a/javatests/dagger/functional/subcomponent/ParentOfGenericComponent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Component;
-import javax.inject.Singleton;
-
-@Component(modules = ParentModule.class)
-@Singleton
-interface ParentOfGenericComponent extends GenericParentComponent<ChildComponent>, ParentGetters {
-}
diff --git a/javatests/dagger/functional/subcomponent/RequiresSingletons.java b/javatests/dagger/functional/subcomponent/RequiresSingletons.java
deleted file mode 100644
index 8dc9b3d..0000000
--- a/javatests/dagger/functional/subcomponent/RequiresSingletons.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import javax.inject.Inject;
-
-final class RequiresSingletons {
-  private final SingletonType singletonType;
-  private final UnscopedType unscopedTypeBoundAsSingleton;
-
-  @Inject RequiresSingletons(SingletonType singletonType,
-      @BoundAsSingleton UnscopedType unscopedTypeBoundAsSingleton) {
-    this.singletonType = singletonType;
-    this.unscopedTypeBoundAsSingleton = unscopedTypeBoundAsSingleton;
-  }
-
-  SingletonType singletonType() {
-    return singletonType;
-  }
-
-  UnscopedType unscopedTypeBoundAsSingleton() {
-    return unscopedTypeBoundAsSingleton;
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/SingletonType.java b/javatests/dagger/functional/subcomponent/SingletonType.java
deleted file mode 100644
index 9a6da6c..0000000
--- a/javatests/dagger/functional/subcomponent/SingletonType.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-final class SingletonType {
-  @Inject SingletonType() {}
-}
diff --git a/javatests/dagger/functional/subcomponent/StaticChildModule.java b/javatests/dagger/functional/subcomponent/StaticChildModule.java
deleted file mode 100644
index fcd0cd5..0000000
--- a/javatests/dagger/functional/subcomponent/StaticChildModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-final class StaticChildModule {
-  private StaticChildModule() {}
-  
-  @Provides static Object provideStaticObject() {
-    return "static";
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/SubcomponentFactoryMethodTest.java b/javatests/dagger/functional/subcomponent/SubcomponentFactoryMethodTest.java
deleted file mode 100644
index ca811af..0000000
--- a/javatests/dagger/functional/subcomponent/SubcomponentFactoryMethodTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2018 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.functional.subcomponent;
-
-import static org.junit.Assert.fail;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for subcomponent factory methods. */
-@RunWith(JUnit4.class)
-public final class SubcomponentFactoryMethodTest {
-
-  @Module
-  static class IntModule {
-    @Provides
-    int provideInt() {
-      return 42;
-    }
-  }
-
-  @Module
-  static class StringModule {
-    final String s;
-
-    StringModule(String s) {
-      this.s = s;
-    }
-
-    @Provides
-    String provideString(int i) {
-      return s + i;
-    }
-  }
-
-  @Component(modules = IntModule.class)
-  interface TestComponent {
-    TestSubcomponent newSubcomponent(StringModule stringModule);
-  }
-
-  @Subcomponent(modules = StringModule.class)
-  interface TestSubcomponent {
-    String string();
-  }
-
-  @Test
-  public void creatingSubcomponentViaFactoryMethod_failsForNullParameter() {
-    TestComponent component = DaggerSubcomponentFactoryMethodTest_TestComponent.create();
-    try {
-      component.newSubcomponent(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/SubcomponentFromModuleAndFactoryMethod.java b/javatests/dagger/functional/subcomponent/SubcomponentFromModuleAndFactoryMethod.java
deleted file mode 100644
index b8b8806..0000000
--- a/javatests/dagger/functional/subcomponent/SubcomponentFromModuleAndFactoryMethod.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Subcomponent;
-
-/**
- * Tests for {@link Subcomponent}s which are defined with {@link Module#subcomponents()} and are
- * also requested as component factory methods.
- */
-public class SubcomponentFromModuleAndFactoryMethod {
-  @Subcomponent
-  interface Sub {
-    @Subcomponent.Builder
-    interface Builder {
-      Sub sub();
-    }
-  }
-
-  @Module(subcomponents = Sub.class)
-  class ModuleWithSubcomponent {}
-
-  @Component(modules = ModuleWithSubcomponent.class)
-  interface ExposesBuilder {
-    Sub.Builder subcomponentBuilder();
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/SubcomponentMultibindingsTest.java b/javatests/dagger/functional/subcomponent/SubcomponentMultibindingsTest.java
deleted file mode 100644
index eeadbeb..0000000
--- a/javatests/dagger/functional/subcomponent/SubcomponentMultibindingsTest.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInChild;
-import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInParent;
-import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInParentAndChild;
-import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithProvisionHasChildWithProvision;
-import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithProvisionHasChildWithoutProvision;
-import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithoutProvisionHasChildWithProvision;
-import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithoutProvisionHasChildWithoutProvision;
-import dagger.functional.subcomponent.MultibindingSubcomponents.RequiresMultibindings;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SubcomponentMultibindingsTest {
-
-  private static final RequiresMultibindings<BoundInParent> BOUND_IN_PARENT =
-      new RequiresMultibindings<>(
-          ImmutableSet.of(BoundInParent.INSTANCE),
-          ImmutableMap.of("parent key", BoundInParent.INSTANCE));
-
-  private static final RequiresMultibindings<BoundInChild> BOUND_IN_CHILD =
-      new RequiresMultibindings<>(
-          ImmutableSet.of(BoundInChild.INSTANCE),
-          ImmutableMap.of("child key", BoundInChild.INSTANCE));
-
-  private static final RequiresMultibindings<BoundInParentAndChild> BOUND_IN_PARENT_AND_CHILD =
-      new RequiresMultibindings<>(
-          ImmutableSet.of(BoundInParentAndChild.IN_PARENT, BoundInParentAndChild.IN_CHILD),
-          ImmutableMap.of(
-              "parent key", BoundInParentAndChild.IN_PARENT,
-              "child key", BoundInParentAndChild.IN_CHILD));
-
-  private static final RequiresMultibindings<BoundInParentAndChild>
-      BOUND_IN_PARENT_AND_CHILD_PROVIDED_BY_PARENT =
-          new RequiresMultibindings<>(
-              ImmutableSet.of(BoundInParentAndChild.IN_PARENT),
-              ImmutableMap.of("parent key", BoundInParentAndChild.IN_PARENT));
-
-  private ParentWithoutProvisionHasChildWithoutProvision
-      parentWithoutProvisionHasChildWithoutProvision;
-  private ParentWithoutProvisionHasChildWithProvision parentWithoutProvisionHasChildWithProvision;
-  private ParentWithProvisionHasChildWithoutProvision parentWithProvisionHasChildWithoutProvision;
-  private ParentWithProvisionHasChildWithProvision parentWithProvisionHasChildWithProvision;
-
-  @Before
-  public void setUp() {
-    parentWithoutProvisionHasChildWithoutProvision =
-        DaggerMultibindingSubcomponents_ParentWithoutProvisionHasChildWithoutProvision.create();
-    parentWithoutProvisionHasChildWithProvision =
-        DaggerMultibindingSubcomponents_ParentWithoutProvisionHasChildWithProvision.create();
-    parentWithProvisionHasChildWithoutProvision =
-        DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithoutProvision.create();
-    parentWithProvisionHasChildWithProvision =
-        DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithProvision.create();
-  }
-
-  @Test
-  public void testParentWithoutProvisionHasChildWithoutProvision() {
-    // Child
-    assertThat(
-            parentWithoutProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-
-    // Grandchild
-    assertThat(
-            parentWithoutProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-    assertThat(
-            parentWithoutProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInChild())
-        .isEqualTo(BOUND_IN_CHILD);
-
-    /*
-     * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
-     * contribution from the child, it must be pushed down to (not duplicated in) the child because
-     * its contribution depends on multibindings that have one contribution from the parent and one
-     * from the child.
-     *
-     */
-    assertThat(
-            parentWithoutProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .setOfRequiresMultibindingsInParentAndChild())
-        .containsExactly(BOUND_IN_PARENT_AND_CHILD);
-  }
-
-  @Test
-  public void testParentWithoutProvisionHasChildWithProvision() {
-    // Child
-    assertThat(
-            parentWithoutProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-
-    // Grandchild
-    assertThat(
-            parentWithoutProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-    assertThat(
-            parentWithoutProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInChild())
-        .isEqualTo(BOUND_IN_CHILD);
-
-    /*
-     * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
-     * contribution from the child, it must be pushed down to (not duplicated in) the child because
-     * its contribution depends on multibindings that have one contribution from the parent and one
-     * from the child.
-     *
-     */
-    assertThat(
-            parentWithoutProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .setOfRequiresMultibindingsInParentAndChild())
-        .containsExactly(BOUND_IN_PARENT_AND_CHILD);
-  }
-
-  @Test
-  public void testParentWithProvisionHasChildWithoutProvision() {
-    // Parent
-    assertThat(parentWithProvisionHasChildWithoutProvision.requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-
-    assertThat(
-            parentWithProvisionHasChildWithoutProvision
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD_PROVIDED_BY_PARENT);
-
-    // Grandchild
-    assertThat(
-            parentWithProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-    assertThat(
-            parentWithProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInChild())
-        .isEqualTo(BOUND_IN_CHILD);
-
-    assertThat(
-            parentWithProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-
-    /*
-     * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
-     * contribution from the child, it must be pushed down to (not duplicated in) the child because
-     * its contribution depends on multibindings that have one contribution from the parent and one
-     * from the child.
-     *
-     */
-    assertThat(
-            parentWithProvisionHasChildWithoutProvision
-                .childWithoutProvision()
-                .grandchild()
-                .setOfRequiresMultibindingsInParentAndChild())
-        .containsExactly(BOUND_IN_PARENT_AND_CHILD);
-  }
-
-  @Test
-  public void testParentWithProvisionHasChildWithProvision() {
-    // Parent
-    assertThat(parentWithProvisionHasChildWithProvision.requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-
-    // Child
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .requiresMultibindingsBoundInChild())
-        .isEqualTo(BOUND_IN_CHILD);
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-
-    // https://github.com/google/dagger/issues/401
-    assertThat(
-        DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithBinds.create()
-            .childWithBinds()
-            .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-
-    /*
-     * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
-     * contribution from the child, it must be pushed down to (not duplicated in) the child because
-     * its contribution depends on multibindings that have one contribution from the parent and one
-     * from the child.
-     *
-     */
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .setOfRequiresMultibindingsInParentAndChild())
-        .containsExactly(BOUND_IN_PARENT_AND_CHILD);
-
-    // Grandchild
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParent())
-        .isEqualTo(BOUND_IN_PARENT);
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInChild())
-        .isEqualTo(BOUND_IN_CHILD);
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .requiresMultibindingsBoundInParentAndChild())
-        .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
-
-    /*
-     * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
-     * contribution from the child, it must be pushed down to (not duplicated in) the child because
-     * its contribution depends on multibindings that have one contribution from the parent and one
-     * from the child.
-     *
-     */
-    assertThat(
-            parentWithProvisionHasChildWithProvision
-                .childWithProvision()
-                .grandchild()
-                .setOfRequiresMultibindingsInParentAndChild())
-        .containsExactly(BOUND_IN_PARENT_AND_CHILD);
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/SubcomponentTest.java b/javatests/dagger/functional/subcomponent/SubcomponentTest.java
deleted file mode 100644
index c34de0a..0000000
--- a/javatests/dagger/functional/subcomponent/SubcomponentTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import static com.google.common.collect.Sets.intersection;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SubcomponentTest {
-  private static final ParentComponent parentComponent = DaggerParentComponent.create();
-  private static final ParentOfGenericComponent parentOfGenericComponent =
-      DaggerParentOfGenericComponent.create();
-
-  @Parameters
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(new Object[][] {
-        { parentComponent, parentComponent.newChildComponent() },
-        { parentComponent, parentComponent.newChildAbstractClassComponent() },
-        { parentOfGenericComponent, parentOfGenericComponent.subcomponent() }});
-  }
-
-  private final ParentGetters parentGetters;
-  private final ChildComponent childComponent;
-
-  public SubcomponentTest(ParentGetters parentGetters, ChildComponent childComponent) {
-    this.parentGetters = parentGetters;
-    this.childComponent = childComponent;
-  }
-
-  @Test
-  public void scopePropagatesUpward_class() {
-    assertThat(childComponent.requiresSingleton().singletonType())
-        .isSameInstanceAs(childComponent.requiresSingleton().singletonType());
-    assertThat(childComponent.requiresSingleton().singletonType())
-        .isSameInstanceAs(
-            childComponent.newGrandchildComponent().requiresSingleton().singletonType());
-  }
-
-  @Test
-  public void scopePropagatesUpward_provides() {
-    assertThat(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton())
-        .isSameInstanceAs(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton());
-    assertThat(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton())
-        .isSameInstanceAs(
-            childComponent
-                .newGrandchildComponent()
-                .requiresSingleton()
-                .unscopedTypeBoundAsSingleton());
-  }
-
-  @Test
-  public void multibindingContributions() {
-    Set<Object> parentObjectSet = parentGetters.objectSet();
-    assertThat(parentObjectSet).hasSize(2);
-    Set<Object> childObjectSet = childComponent.objectSet();
-    assertThat(childObjectSet).hasSize(3);
-    Set<Object> grandchildObjectSet =
-        childComponent.newGrandchildComponent().objectSet();
-    assertThat(grandchildObjectSet).hasSize(4);
-    assertThat(intersection(parentObjectSet, childObjectSet)).hasSize(1);
-    assertThat(intersection(parentObjectSet, grandchildObjectSet)).hasSize(1);
-    assertThat(intersection(childObjectSet, grandchildObjectSet)).hasSize(1);
-  }
-
-  @Test
-  public void unscopedProviders() {
-    assume().that(System.getProperty("dagger.mode")).doesNotContain("FastInit");
-    assertThat(parentGetters.getUnscopedTypeProvider())
-        .isSameInstanceAs(childComponent.getUnscopedTypeProvider());
-    assertThat(parentGetters.getUnscopedTypeProvider())
-        .isSameInstanceAs(childComponent.newGrandchildComponent().getUnscopedTypeProvider());
-  }
-
-  @Test
-  public void passedModules() {
-    ChildModuleWithState childModuleWithState = new ChildModuleWithState();
-    ChildComponentRequiringModules childComponent1 =
-        parentComponent.newChildComponentRequiringModules(
-            new ChildModuleWithParameters(new Object()),
-            childModuleWithState);
-    ChildComponentRequiringModules childComponent2 =
-        parentComponent.newChildComponentRequiringModules(
-            new ChildModuleWithParameters(new Object()),
-            childModuleWithState);
-    assertThat(childComponent1.getInt()).isEqualTo(0);
-    assertThat(childComponent2.getInt()).isEqualTo(1);
-  }
-
-  @Test
-  public void dependenceisInASubcomponent() {
-    assertThat(childComponent.newGrandchildComponent().needsAnInterface()).isNotNull();
-  }
-
-  @Test
-  public void qualifiedSubcomponentIsBound() {
-    assertThat(parentComponent.unresolvableChildComponentBuilder().build().unboundString())
-        .isEqualTo("unbound");
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/Unbound.java b/javatests/dagger/functional/subcomponent/Unbound.java
deleted file mode 100644
index ae80621..0000000
--- a/javatests/dagger/functional/subcomponent/Unbound.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-
-/**
- * A qualifier representing an unbound type, to verify that the compiler does not attempt to
- * generate code depending on it.
- */
-@Documented
-@Retention(RUNTIME)
-@Qualifier
-@interface Unbound {}
diff --git a/javatests/dagger/functional/subcomponent/UnresolvableChildComponent.java b/javatests/dagger/functional/subcomponent/UnresolvableChildComponent.java
deleted file mode 100644
index 57d9d0d..0000000
--- a/javatests/dagger/functional/subcomponent/UnresolvableChildComponent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import dagger.Subcomponent;
-
-/**
- * A subcomponent that's not resolvable in any parent component, for testing that qualified methods
- * on components that return subcomponents do not trigger actual subcomponents.
- */
-@Subcomponent
-interface UnresolvableChildComponent {
-  /**
-   * Requests a type that is never bound in any component that this subcomponent might be installed
-   * in. If this subcomponent is ever attempted to be installed in a component, then it will produce
-   * a compiler error.
-   */
-  @Unbound
-  String unboundString();
-
-  @Subcomponent.Builder
-  interface Builder {
-    UnresolvableChildComponent build();
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/UnresolvableChildComponentModule.java b/javatests/dagger/functional/subcomponent/UnresolvableChildComponentModule.java
deleted file mode 100644
index 613e7e3..0000000
--- a/javatests/dagger/functional/subcomponent/UnresolvableChildComponentModule.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.functional.SomeQualifier;
-
-@Module
-final class UnresolvableChildComponentModule {
-  /**
-   * Provides a qualified version of the {@link UnresolvableChildComponent}'s builder. If the
-   * subcomponent were actually installed in a component, this would be a duplicate binding; but
-   * since that doesn't happen, this binding is OK.
-   */
-  @Provides
-  @SomeQualifier
-  static UnresolvableChildComponent.Builder unresolvableChildComponentBuilder() {
-    return new UnresolvableChildComponent.Builder() {
-      @Override
-      public UnresolvableChildComponent build() {
-        return new UnresolvableChildComponent() {
-          @Override
-          public String unboundString() {
-            return "unbound";
-          }
-        };
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/UnscopedType.java b/javatests/dagger/functional/subcomponent/UnscopedType.java
deleted file mode 100644
index c167457..0000000
--- a/javatests/dagger/functional/subcomponent/UnscopedType.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent;
-
-import javax.inject.Inject;
-
-final class UnscopedType {
-  @Inject UnscopedType(@SuppressWarnings("unused") SingletonType singletonType) {}
-}
diff --git a/javatests/dagger/functional/subcomponent/UsesModuleSubcomponents.java b/javatests/dagger/functional/subcomponent/UsesModuleSubcomponents.java
deleted file mode 100644
index bd240af..0000000
--- a/javatests/dagger/functional/subcomponent/UsesModuleSubcomponents.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoSet;
-import java.util.Set;
-import javax.inject.Inject;
-
-/** Supporting types for {@link ModuleWithSubcomponentsTest}. */
-@Component(modules = UsesModuleSubcomponents.ModuleWithSubcomponents.class)
-public interface UsesModuleSubcomponents {
-  UsesChild usesChild();
-
-  Set<String> strings();
-
-  @Module(subcomponents = Child.class, includes = AlsoIncludesSubcomponents.class)
-  class ModuleWithSubcomponents {
-    @Provides
-    @IntoSet
-    static String provideStringInParent() {
-      return "from parent";
-    }
-  }
-
-  @Module(subcomponents = Child.class)
-  class AlsoIncludesSubcomponents {}
-
-  @Subcomponent(modules = ChildModule.class)
-  interface Child {
-    Set<String> strings();
-
-    @Subcomponent.Builder
-    interface Builder {
-      Child build();
-    }
-  }
-
-  @Module
-  class ChildModule {
-    @Provides
-    @IntoSet
-    static String provideStringInChild() {
-      return "from child";
-    }
-  }
-
-  class UsesChild {
-    Set<String> strings;
-
-    @Inject
-    UsesChild(Child.Builder childBuilder) {
-      this.strings = childBuilder.build().strings();
-    }
-  }
-
-  @Module(includes = ModuleWithSubcomponents.class)
-  class OnlyIncludesModuleWithSubcomponents {}
-
-  @Component(modules = OnlyIncludesModuleWithSubcomponents.class)
-  interface ParentIncludesSubcomponentTransitively extends UsesModuleSubcomponents {}
-
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/ChildComponent.java b/javatests/dagger/functional/subcomponent/hiding/ChildComponent.java
deleted file mode 100644
index 7cb4fce..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/ChildComponent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = dagger.functional.subcomponent.hiding.b.CommonModuleName.class)
-interface ChildComponent {
-  //ensure that t.s.h.a.CommonName gets bound in this component
-  dagger.functional.subcomponent.hiding.a.CommonName aCommonName();
-  //ensure that t.s.h.b.CommonName gets bound in this component
-  dagger.functional.subcomponent.hiding.b.CommonName bCommonName();
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/ParentComponent.java b/javatests/dagger/functional/subcomponent/hiding/ParentComponent.java
deleted file mode 100644
index 7458d82..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/ParentComponent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding;
-
-import dagger.Component;
-import javax.inject.Singleton;
-
-@Component(modules = dagger.functional.subcomponent.hiding.a.CommonModuleName.class)
-@Singleton
-interface ParentComponent {
-  // ensure that t.s.h.a.CommonName gets bound in this component
-  dagger.functional.subcomponent.hiding.a.CommonName aCommonName();
-
-  ChildComponent newChildComponent();
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/SubcomponentHidingTest.java b/javatests/dagger/functional/subcomponent/hiding/SubcomponentHidingTest.java
deleted file mode 100644
index 398b8a7..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/SubcomponentHidingTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SubcomponentHidingTest {
-  @Test public void moduleNameHiding() {
-    ParentComponent parent = DaggerParentComponent.create();
-    assertThat(parent.aCommonName().toString()).isEqualTo("a");
-    assertThat(parent.newChildComponent().aCommonName().toString()).isEqualTo("a");
-    assertThat(parent.newChildComponent().bCommonName().toString()).isEqualTo("1");
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/a/CommonModuleName.java b/javatests/dagger/functional/subcomponent/hiding/a/CommonModuleName.java
deleted file mode 100644
index d13446c..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/a/CommonModuleName.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding.a;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public class CommonModuleName {
-  @Provides String provideString() {
-    return "a";
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/a/CommonName.java b/javatests/dagger/functional/subcomponent/hiding/a/CommonName.java
deleted file mode 100644
index 567fc39..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/a/CommonName.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding.a;
-
-import javax.inject.Inject;
-
-public final class CommonName {
-  private final String s;
-
-  @Inject CommonName(String s) {
-    this.s = s;
-  }
-
-  @Override
-  public String toString() {
-    return s;
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/b/CommonModuleName.java b/javatests/dagger/functional/subcomponent/hiding/b/CommonModuleName.java
deleted file mode 100644
index b05356f..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/b/CommonModuleName.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding.b;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public class CommonModuleName {
-  @Provides int provideString() {
-    return 1;
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/hiding/b/CommonName.java b/javatests/dagger/functional/subcomponent/hiding/b/CommonName.java
deleted file mode 100644
index 1136f64..0000000
--- a/javatests/dagger/functional/subcomponent/hiding/b/CommonName.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.hiding.b;
-
-import javax.inject.Inject;
-
-public final class CommonName {
-  private final int i;
-
-  @Inject CommonName(int i) {
-    this.i = i;
-  }
-
-  @Override
-  public String toString() {
-    return Integer.toString(i);
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/pruning/ParentDoesntUseSubcomponent.java b/javatests/dagger/functional/subcomponent/pruning/ParentDoesntUseSubcomponent.java
deleted file mode 100644
index 516a52c..0000000
--- a/javatests/dagger/functional/subcomponent/pruning/ParentDoesntUseSubcomponent.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent.pruning;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.multibindings.IntoSet;
-import java.util.Set;
-import javax.inject.Qualifier;
-
-/**
- * Supporting types for {@link SubcomponentOnlyRequestedBySiblingTest}. {@link ChildA} is a direct
- * child of the top level component, but is only requested within its sibling, not directly from its
- * parent.
- */
-@Component(modules = ParentDoesntUseSubcomponent.ParentModule.class)
-interface ParentDoesntUseSubcomponent {
-
-  ChildB.Builder childBBuilder();
-
-  @Subcomponent(modules = ChildAModule.class)
-  interface ChildA {
-    @Subcomponent.Builder
-    interface Builder {
-      ChildA build();
-    }
-
-    Set<Class<?>> componentHierarchy();
-  }
-
-  @Subcomponent(modules = ChildBModule.class)
-  interface ChildB {
-    @Subcomponent.Builder
-    interface Builder {
-      ChildB build();
-    }
-
-    Set<Class<?>> componentHierarchy();
-
-    @FromChildA
-    Set<Class<?>> componentHierarchyFromChildA();
-  }
-
-  @Module(subcomponents = {ChildA.class, ChildB.class})
-  class ParentModule {
-    @Provides
-    @IntoSet
-    static Class<?> provideComponentType() {
-      return ParentDoesntUseSubcomponent.class;
-    }
-  }
-
-  @Module
-  class ChildAModule {
-    @Provides
-    @IntoSet
-    static Class<?> provideComponentType() {
-      return ChildA.class;
-    }
-  }
-
-  @Module
-  class ChildBModule {
-    @Provides
-    @IntoSet
-    static Class<?> provideComponentType() {
-      return ChildB.class;
-    }
-
-    @Provides
-    @FromChildA
-    Set<Class<?>> fromChildA(ChildA.Builder childABuilder) {
-      return childABuilder.build().componentHierarchy();
-    }
-  }
-
-  @Qualifier
-  @interface FromChildA {}
-}
diff --git a/javatests/dagger/functional/subcomponent/pruning/SubcomponentOnlyRequestedBySiblingTest.java b/javatests/dagger/functional/subcomponent/pruning/SubcomponentOnlyRequestedBySiblingTest.java
deleted file mode 100644
index 40a784a..0000000
--- a/javatests/dagger/functional/subcomponent/pruning/SubcomponentOnlyRequestedBySiblingTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2016 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.functional.subcomponent.pruning;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import dagger.Module;
-import dagger.Subcomponent;
-import dagger.functional.subcomponent.pruning.ParentDoesntUseSubcomponent.ChildA;
-import dagger.functional.subcomponent.pruning.ParentDoesntUseSubcomponent.ChildB;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link Subcomponent}s which are included with {@link Module#subcomponents()} but not
- * used directly within the component which adds them.
- *
- * <p>This tests to make sure that while resolving one subcomponent (A), another subcomponent (B)
- * can be requested if they have a shared ancestor component. If that shared ancestor did not
- * resolve B directly via any of its entry points, B will still be generated since it is requested
- * by a descendant.
- */
-@RunWith(JUnit4.class)
-public class SubcomponentOnlyRequestedBySiblingTest {
-  @Test
-  public void subcomponentAddedInParent_onlyUsedInSibling() {
-    ParentDoesntUseSubcomponent parent = DaggerParentDoesntUseSubcomponent.create();
-    ChildB childB = parent.childBBuilder().build();
-    assertThat(childB.componentHierarchy())
-        .containsExactly(ParentDoesntUseSubcomponent.class, ChildB.class);
-    assertThat(childB.componentHierarchyFromChildA())
-        .containsExactly(ParentDoesntUseSubcomponent.class, ChildA.class);
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInChild.java b/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInChild.java
deleted file mode 100644
index b3318cf..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInChild.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-abstract class OnlyUsedInChild {
-
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInParent.java b/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInParent.java
deleted file mode 100644
index 1e8d4cd..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/OnlyUsedInParent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-abstract class OnlyUsedInParent {
-
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/OtherSubcomponentWithRepeatedModule.java b/javatests/dagger/functional/subcomponent/repeat/OtherSubcomponentWithRepeatedModule.java
deleted file mode 100644
index 82cd021..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/OtherSubcomponentWithRepeatedModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import dagger.Subcomponent;
-
-@Subcomponent(modules = RepeatedModule.class)
-interface OtherSubcomponentWithRepeatedModule extends SubcomponentWithRepeatedModule {
-
-  @Subcomponent.Builder
-  interface Builder {
-    Builder repeatedModule(RepeatedModule repeatedModule);
-
-    OtherSubcomponentWithRepeatedModule build();
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/ParentComponent.java b/javatests/dagger/functional/subcomponent/repeat/ParentComponent.java
deleted file mode 100644
index 1578596..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/ParentComponent.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import dagger.Component;
-import java.util.Set;
-
-@Component(modules = RepeatedModule.class)
-interface ParentComponent {
-  Object state();
-
-  String getString();
-  Set<String> getMultiboundStrings();
-  OnlyUsedInParent getOnlyUsedInParent();
-
-  SubcomponentWithRepeatedModule.Builder newChildComponentBuilder();
-
-  SubcomponentWithoutRepeatedModule newChildComponentWithoutRepeatedModule();
-
-  @Component.Builder
-  interface Builder {
-    Builder repeatedModule(RepeatedModule repeatedModule);
-
-    ParentComponent build();
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/RepeatedModule.java b/javatests/dagger/functional/subcomponent/repeat/RepeatedModule.java
deleted file mode 100644
index 55d7de9..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/RepeatedModule.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoSet;
-
-@Module
-final class RepeatedModule {
-  private final Object state = new Object();
-
-  @Provides
-  Object state() {
-    return state;
-  }
-
-  @Provides
-  static String provideString() {
-    return "a string";
-  }
-
-  @Provides
-  @IntoSet
-  static String contributeString() {
-    return "a string in a set";
-  }
-
-  @Provides
-  static OnlyUsedInParent provideOnlyUsedInParent() {
-    return new OnlyUsedInParent() {};
-  }
-
-  @Provides
-  static OnlyUsedInChild provideOnlyUsedInChild() {
-    return new OnlyUsedInChild() {};
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/RepeatedModuleTest.java b/javatests/dagger/functional/subcomponent/repeat/RepeatedModuleTest.java
deleted file mode 100644
index 9bf3a39..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/RepeatedModuleTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class RepeatedModuleTest {
-  private ParentComponent parentComponent;
-
-  @Before
-  public void initializeParentComponent() {
-    this.parentComponent = DaggerParentComponent.builder().build();
-  }
-
-  @Test
-  public void repeatedModuleHasSameStateInSubcomponent() {
-    SubcomponentWithRepeatedModule childComponent =
-        parentComponent.newChildComponentBuilder().build();
-    assertThat(parentComponent.state()).isSameInstanceAs(childComponent.state());
-  }
-
-  @Test
-  public void repeatedModuleHasSameStateInGrandchildSubcomponent() {
-    SubcomponentWithoutRepeatedModule childComponent =
-        parentComponent.newChildComponentWithoutRepeatedModule();
-    SubcomponentWithRepeatedModule grandchildComponent =
-        childComponent.newGrandchildBuilder().build();
-    assertThat(parentComponent.state()).isSameInstanceAs(grandchildComponent.state());
-  }
-
-  @Test
-  public void repeatedModuleBuilderThrowsInSubcomponent() {
-    SubcomponentWithRepeatedModule.Builder childComponentBuilder =
-        parentComponent.newChildComponentBuilder();
-    try {
-      childComponentBuilder.repeatedModule(new RepeatedModule());
-      fail();
-    } catch (UnsupportedOperationException expected) {
-      assertThat(expected)
-          .hasMessageThat()
-          .isEqualTo(
-              "dagger.functional.subcomponent.repeat.RepeatedModule cannot be set "
-                  + "because it is inherited from the enclosing component");
-    }
-  }
-
-  @Test
-  public void repeatedModuleBuilderThrowsInGrandchildSubcomponent() {
-    SubcomponentWithoutRepeatedModule childComponent =
-        parentComponent.newChildComponentWithoutRepeatedModule();
-    OtherSubcomponentWithRepeatedModule.Builder grandchildComponentBuilder =
-        childComponent.newGrandchildBuilder();
-    try {
-      grandchildComponentBuilder.repeatedModule(new RepeatedModule());
-      fail();
-    } catch (UnsupportedOperationException expected) {
-      assertThat(expected)
-          .hasMessageThat()
-          .isEqualTo(
-              "dagger.functional.subcomponent.repeat.RepeatedModule cannot be set "
-                  + "because it is inherited from the enclosing component");
-    }
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithRepeatedModule.java b/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithRepeatedModule.java
deleted file mode 100644
index 0762374..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithRepeatedModule.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import dagger.Subcomponent;
-import java.util.Set;
-
-@Subcomponent(modules = RepeatedModule.class)
-interface SubcomponentWithRepeatedModule {
-  Object state();
-
-  String getString();
-
-  Set<String> getMultiboundStrings();
-
-  OnlyUsedInChild getOnlyUsedInChild();
-
-  @Subcomponent.Builder
-  interface Builder {
-    Builder repeatedModule(RepeatedModule repeatedModule);
-
-    SubcomponentWithRepeatedModule build();
-  }
-}
diff --git a/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java b/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java
deleted file mode 100644
index 5930f51..0000000
--- a/javatests/dagger/functional/subcomponent/repeat/SubcomponentWithoutRepeatedModule.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.subcomponent.repeat;
-
-import dagger.Subcomponent;
-
-@Subcomponent
-interface SubcomponentWithoutRepeatedModule {
-  OtherSubcomponentWithRepeatedModule.Builder newGrandchildBuilder();
-}
diff --git a/javatests/dagger/functional/tck/BUILD b/javatests/dagger/functional/tck/BUILD
deleted file mode 100644
index 7526bf0..0000000
--- a/javatests/dagger/functional/tck/BUILD
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#  TCK tests for Dagger
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "tck_tests",
-    srcs = glob(["*.java"]),
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    lib_javacopts = [
-        "-Adagger.privateMemberValidation=warning",
-        "-Adagger.staticMemberValidation=warning",
-        "-Adagger.ignorePrivateAndStaticInjectionForComponent=enabled",
-    ],
-    deps = [
-        "//:dagger_with_compiler",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/jsr330_inject:tck",
-        "@google_bazel_common//third_party/java/junit",
-    ],
-)
diff --git a/javatests/dagger/functional/tck/CarModule.java b/javatests/dagger/functional/tck/CarModule.java
deleted file mode 100644
index 3c44d60..0000000
--- a/javatests/dagger/functional/tck/CarModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.Binds;
-import dagger.Module;
-import org.atinject.tck.auto.Car;
-import org.atinject.tck.auto.Convertible;
-
-@Module
-abstract class CarModule {
-  @Binds
-  abstract Car provideConvertible(Convertible convertible);
-}
diff --git a/javatests/dagger/functional/tck/CarShop.java b/javatests/dagger/functional/tck/CarShop.java
deleted file mode 100644
index d9e64d6..0000000
--- a/javatests/dagger/functional/tck/CarShop.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.Component;
-import javax.inject.Singleton;
-import org.atinject.tck.auto.Car;
-
-@Singleton
-@Component(
-  modules = {
-    CarModule.class,
-    TireModule.class,
-    SeatModule.class,
-    EngineModule.class,
-    FuelTankModule.class
-  }
-)
-public interface CarShop {
-  @SuppressWarnings("dependency-cycle")
-  Car make();
-}
diff --git a/javatests/dagger/functional/tck/EngineModule.java b/javatests/dagger/functional/tck/EngineModule.java
deleted file mode 100644
index 331b064..0000000
--- a/javatests/dagger/functional/tck/EngineModule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.MembersInjector;
-import dagger.Module;
-import dagger.Provides;
-import org.atinject.tck.auto.Engine;
-import org.atinject.tck.auto.V8Engine;
-
-@Module
-public class EngineModule {
-  @Provides
-  static Engine provideEngine(MembersInjector<V8Engine> injector) {
-    // This is provided because V8Engine has no @Inject constructor and Dagger requires an @Inject
-    // constructor, however this is a TCK supplied class that we prefer to leave unmodified.
-    V8Engine engine = new V8Engine();
-    injector.injectMembers(engine);
-    return engine;
-  }
-}
diff --git a/javatests/dagger/functional/tck/FuelTankModule.java b/javatests/dagger/functional/tck/FuelTankModule.java
deleted file mode 100644
index b5f2800..0000000
--- a/javatests/dagger/functional/tck/FuelTankModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.Module;
-import dagger.Provides;
-import org.atinject.tck.auto.FuelTank;
-
-@Module
-class FuelTankModule {
-  @Provides
-  static FuelTank provideFuelTank() {
-    return new FuelTank();
-  }
-}
diff --git a/javatests/dagger/functional/tck/SeatModule.java b/javatests/dagger/functional/tck/SeatModule.java
deleted file mode 100644
index c3574ea..0000000
--- a/javatests/dagger/functional/tck/SeatModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.Binds;
-import dagger.Module;
-import org.atinject.tck.auto.Drivers;
-import org.atinject.tck.auto.DriversSeat;
-import org.atinject.tck.auto.Seat;
-
-@Module
-abstract class SeatModule {
-  @Binds
-  @Drivers
-  abstract Seat provideSeat(DriversSeat seat);
-}
diff --git a/javatests/dagger/functional/tck/TckTest.java b/javatests/dagger/functional/tck/TckTest.java
deleted file mode 100644
index a49972d..0000000
--- a/javatests/dagger/functional/tck/TckTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import junit.framework.Test;
-import org.atinject.tck.Tck;
-import org.atinject.tck.auto.Car;
-import org.atinject.tck.auto.Convertible;
-
-/** 
- * Test suite to execute the JSR-330 TCK in JUnit.
- */
-public class TckTest {
-  public static Test suite() {
-    CarShop carShopComponent = DaggerCarShop.create();
-    Car car = carShopComponent.make();
-    Convertible.localConvertible.set((Convertible) car);
-    return Tck.testsFor(car, false, false);
-  }
-}
diff --git a/javatests/dagger/functional/tck/TireModule.java b/javatests/dagger/functional/tck/TireModule.java
deleted file mode 100644
index e6b6d58..0000000
--- a/javatests/dagger/functional/tck/TireModule.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 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.functional.tck;
-
-import dagger.Binds;
-import dagger.Module;
-import javax.inject.Named;
-import org.atinject.tck.auto.Tire;
-import org.atinject.tck.auto.accessories.SpareTire;
-
-@Module
-abstract class TireModule {
-  @Binds
-  @Named("spare")
-  abstract Tire provideTire(SpareTire sparetire);
-}
diff --git a/javatests/dagger/grpc/functional/server/BUILD b/javatests/dagger/grpc/functional/server/BUILD
deleted file mode 100644
index 1e8c2e6..0000000
--- a/javatests/dagger/grpc/functional/server/BUILD
+++ /dev/null
@@ -1,19 +0,0 @@
-# Functional tests for Dagger-gRPC
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES")
-load("//:test_defs.bzl", "GenJavaTests")
-
-# TODO(dpb): enable tests once java_grpc_library is ready in bazel:
-# https://github.com/grpc/grpc-java/issues/2756
-
-java_proto_library(
-    name = "coffee_service_java_proto",
-    deps = [":protos"],
-)
-
-proto_library(
-    name = "protos",
-    srcs = glob(["*.proto"]),
-)
diff --git a/javatests/dagger/grpc/functional/server/BaristaTest.java b/javatests/dagger/grpc/functional/server/BaristaTest.java
deleted file mode 100644
index d6c5b42..0000000
--- a/javatests/dagger/grpc/functional/server/BaristaTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.util.concurrent.Futures.getUnchecked;
-import static com.google.protos.test.CoffeeService.CoffeeType.AMERICANO;
-import static com.google.protos.test.CoffeeService.CoffeeType.DRIP;
-import static com.google.protos.test.CoffeeService.CoffeeType.ESPRESSO;
-import static com.google.protos.test.CoffeeService.CoffeeType.LATTE;
-import static com.google.protos.test.CoffeeService.CoffeeType.POUR_OVER;
-import static java.util.Arrays.asList;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.SettableFuture;
-import com.google.protos.test.BaristaGrpc;
-import com.google.protos.test.BaristaGrpc.BaristaStub;
-import com.google.protos.test.CoffeeService.CoffeeRequest;
-import com.google.protos.test.CoffeeService.CoffeeResponse;
-import com.google.protos.test.CoffeeService.CoffeeType;
-import io.grpc.inprocess.InProcessChannelBuilder;
-import io.grpc.stub.StreamObserver;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class BaristaTest {
-
-  private static final class CoffeeResponseObserver implements StreamObserver<CoffeeResponse> {
-    private final SettableFuture<Void> completion = SettableFuture.create();
-    private final List<CoffeeResponse> responses = new ArrayList<>();
-
-    List<CoffeeResponse> responses() {
-      getUnchecked(completion);
-      return responses;
-    }
-
-    @Override
-    public void onNext(CoffeeResponse value) {
-      responses.add(value);
-    }
-
-    @Override
-    public void onError(Throwable t) {
-      completion.setException(t);
-    }
-
-    @Override
-    public void onCompleted() {
-      completion.set(null);
-    }
-  }
-
-  @ClassRule
-  public static CoffeeServerResource coffeeServerWithCallScope =
-      new CoffeeServerResource("CallScope", DaggerCoffeeServerWithCallScopeService.builder());
-
-  @ClassRule
-  public static CoffeeServerResource coffeeServerWithSingletonScope =
-      new CoffeeServerResource("Unscoped", DaggerCoffeeServerWithUnscopedService.builder());
-
-  @Parameters(name = "{0}")
-  public static Iterable<Object[]> coffeeServers() {
-    return ImmutableList.copyOf(
-        new Object[][] {{coffeeServerWithCallScope}, {coffeeServerWithSingletonScope}});
-  }
-
-  @Rule public final VerifyInterceptor verifyCount;
-  private final CoffeeServerResource coffeeServer;
-  private final CoffeeResponseObserver responseObserver = new CoffeeResponseObserver();
-
-  private BaristaStub barista;
-
-  public BaristaTest(CoffeeServerResource coffeeServer) {
-    this.coffeeServer = coffeeServer;
-    this.verifyCount = new VerifyInterceptor(coffeeServer);
-  }
-
-  @Before
-  public void setUp() {
-    barista = BaristaGrpc.newStub(InProcessChannelBuilder.forName(coffeeServer.name()).build());
-  }
-
-  @Test
-  public void testUnaryGetCoffee() {
-    barista.unaryGetCoffee(request(POUR_OVER, LATTE), responseObserver);
-    assertThat(responseObserver.responses())
-        .containsExactly(response("Here you go!", POUR_OVER, LATTE));
-  }
-
-  @Test
-  public void testClientStreamingGetCoffee() {
-    StreamObserver<CoffeeRequest> requestObserver =
-        barista.clientStreamingGetCoffee(responseObserver);
-    requestObserver.onNext(request(POUR_OVER, LATTE));
-    requestObserver.onNext(request(AMERICANO));
-    requestObserver.onNext(request(DRIP, ESPRESSO));
-    requestObserver.onCompleted();
-    assertThat(responseObserver.responses())
-        .containsExactly(response("All yours!", POUR_OVER, LATTE, AMERICANO, DRIP, ESPRESSO));
-  }
-
-  @Test
-  public void testServerStreamingGetCoffee() {
-    barista.serverStreamingGetCoffee(request(DRIP, AMERICANO), responseObserver);
-    assertThat(responseObserver.responses())
-        .containsExactly(
-            response("Here's a DRIP", DRIP), response("Here's a AMERICANO", AMERICANO));
-  }
-
-  @Test
-  public void testBidiStreamingGetCoffee() {
-    StreamObserver<CoffeeRequest> requestObserver =
-        barista.bidiStreamingGetCoffee(responseObserver);
-    requestObserver.onNext(request(POUR_OVER, LATTE));
-    requestObserver.onNext(request(AMERICANO));
-    requestObserver.onNext(request(DRIP, ESPRESSO));
-    requestObserver.onCompleted();
-    assertThat(responseObserver.responses())
-        .containsExactly(
-            response("Enjoy!", POUR_OVER, LATTE),
-            response("Enjoy!", AMERICANO),
-            response("Enjoy!", DRIP, ESPRESSO));
-  }
-
-  private CoffeeRequest request(CoffeeType... types) {
-    return CoffeeRequest.newBuilder().addAllType(asList(types)).build();
-  }
-
-  private CoffeeResponse response(String message, CoffeeType... types) {
-    return CoffeeResponse.newBuilder().setMessage(message).addAllCup(asList(types)).build();
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/CoffeeServer.java b/javatests/dagger/grpc/functional/server/CoffeeServer.java
deleted file mode 100644
index 10a0fd2..0000000
--- a/javatests/dagger/grpc/functional/server/CoffeeServer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import dagger.grpc.server.InProcessServerModule;
-import io.grpc.Server;
-import java.io.IOException;
-
-abstract class CoffeeServer<T extends CoffeeServer<T>> {
-  protected abstract Server server();
-
-  public void start() throws IOException {
-    server().start();
-  }
-
-  public void shutdown() {
-    server().shutdownNow();
-  }
-
-  abstract CountingInterceptor countingInterceptor();
-
-  interface Builder<T extends CoffeeServer<T>> {
-    Builder<T> inProcessServerModule(InProcessServerModule serverModule);
-
-    T build();
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/CoffeeServerResource.java b/javatests/dagger/grpc/functional/server/CoffeeServerResource.java
deleted file mode 100644
index dc449fb..0000000
--- a/javatests/dagger/grpc/functional/server/CoffeeServerResource.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import dagger.grpc.server.InProcessServerModule;
-import java.io.IOException;
-import org.junit.rules.ExternalResource;
-
-final class CoffeeServerResource extends ExternalResource {
-  private final String name;
-  private final CoffeeServer<?> coffeeServer;
-
-  CoffeeServerResource(String name, CoffeeServer.Builder<?> coffeeServerBuilder) {
-    this.name = name;
-    this.coffeeServer =
-        coffeeServerBuilder.inProcessServerModule(InProcessServerModule.serverNamed(name)).build();
-  }
-
-  public String name() {
-    return name;
-  }
-
-  public int methodCount(String methodName) {
-    return coffeeServer.countingInterceptor().countCalls(methodName);
-  }
-
-  @Override
-  protected void before() throws IOException, InterruptedException {
-    coffeeServer.start();
-  }
-
-  @Override
-  protected void after() {
-    coffeeServer.shutdown();
-  }
-
-  @Override
-  public String toString() {
-    return name;
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/CoffeeServerWithCallScopeService.java b/javatests/dagger/grpc/functional/server/CoffeeServerWithCallScopeService.java
deleted file mode 100644
index 5fb06b6..0000000
--- a/javatests/dagger/grpc/functional/server/CoffeeServerWithCallScopeService.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-import dagger.grpc.functional.server.CoffeeServerWithCallScopeService.CallScopeServiceModule;
-import dagger.grpc.functional.server.CountingInterceptor.CountingInterceptorModule;
-import dagger.grpc.server.CallScoped;
-import dagger.grpc.server.GrpcCallMetadataModule;
-import dagger.grpc.server.InProcessServerModule;
-import javax.inject.Singleton;
-
-@Singleton
-@Component(modules = {InProcessServerModule.class, CallScopeServiceModule.class})
-abstract class CoffeeServerWithCallScopeService
-    extends CoffeeServer<CoffeeServerWithCallScopeService> {
-
-  @Component.Builder
-  interface Builder extends CoffeeServer.Builder<CoffeeServerWithCallScopeService> {}
-
-  abstract BaristaCallScope baristaCallScope(GrpcCallMetadataModule callMetadataModule);
-
-  @CallScoped
-  @Subcomponent(
-    modules = {
-      GrpcCallMetadataModule.class,
-      FriendlyBaristaGrpcServiceModule.class,
-      CountingInterceptorModule.class
-    }
-  )
-  interface BaristaCallScope extends FriendlyBaristaServiceDefinition {}
-
-  @Module(includes = FriendlyBaristaGrpcProxyModule.class)
-  static class CallScopeServiceModule {
-    @Provides
-    static FriendlyBaristaServiceDefinition.Factory friendlyBaristaServiceDefinitionFactory(
-        final CoffeeServerWithCallScopeService testServer) {
-      return new FriendlyBaristaServiceDefinition.Factory() {
-        @Override
-        public FriendlyBaristaServiceDefinition grpcService(
-            GrpcCallMetadataModule grpcCallMetadataModule) {
-          return testServer.baristaCallScope(grpcCallMetadataModule);
-        }
-      };
-    }
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/CoffeeServerWithUnscopedService.java b/javatests/dagger/grpc/functional/server/CoffeeServerWithUnscopedService.java
deleted file mode 100644
index 3346f84..0000000
--- a/javatests/dagger/grpc/functional/server/CoffeeServerWithUnscopedService.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import dagger.Binds;
-import dagger.Component;
-import dagger.Module;
-import dagger.grpc.functional.server.CoffeeServerWithUnscopedService.UnscopedServiceModule;
-import dagger.grpc.functional.server.CountingInterceptor.CountingInterceptorModule;
-import dagger.grpc.server.InProcessServerModule;
-import javax.inject.Singleton;
-
-@Singleton
-@Component(
-  modules = {
-    InProcessServerModule.class,
-    UnscopedServiceModule.class,
-    CountingInterceptorModule.class
-  }
-)
-abstract class CoffeeServerWithUnscopedService extends CoffeeServer<CoffeeServerWithUnscopedService>
-    implements FriendlyBaristaServiceDefinition {
-
-  @Component.Builder
-  interface Builder extends CoffeeServer.Builder<CoffeeServerWithUnscopedService> {}
-
-  @Module(includes = FriendlyBaristaUnscopedGrpcServiceModule.class)
-  abstract static class UnscopedServiceModule {
-    @Binds
-    abstract FriendlyBaristaServiceDefinition friendlyBaristaServiceDefinition(
-        CoffeeServerWithUnscopedService testServer);
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/CountingInterceptor.java b/javatests/dagger/grpc/functional/server/CountingInterceptor.java
deleted file mode 100644
index 4d53782..0000000
--- a/javatests/dagger/grpc/functional/server/CountingInterceptor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import static java.util.Arrays.asList;
-
-import com.google.common.collect.ConcurrentHashMultiset;
-import com.google.common.collect.Multiset;
-import com.google.protos.test.BaristaGrpc;
-import dagger.Module;
-import dagger.Provides;
-import dagger.grpc.server.ForGrpcService;
-import io.grpc.Metadata;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import java.util.List;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-class CountingInterceptor implements ServerInterceptor {
-  private final Multiset<String> calls = ConcurrentHashMultiset.create();
-
-  @Inject
-  CountingInterceptor() {}
-
-  @Override
-  public <RequestT, ResponseT> Listener<RequestT> interceptCall(
-      ServerCall<RequestT, ResponseT> call,
-      Metadata headers,
-      ServerCallHandler<RequestT, ResponseT> next) {
-    calls.add(call.getMethodDescriptor().getFullMethodName());
-    return next.startCall(call, headers);
-  }
-
-  public int countCalls(String methodName) {
-    return calls.count(methodName);
-  }
-
-  @Module
-  static class CountingInterceptorModule {
-    @Provides
-    @ForGrpcService(BaristaGrpc.class)
-    static List<? extends ServerInterceptor> testServiceInterceptors(
-        CountingInterceptor countingInterceptor) {
-      return asList(countingInterceptor);
-    }
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/FriendlyBarista.java b/javatests/dagger/grpc/functional/server/FriendlyBarista.java
deleted file mode 100644
index 2c0246f..0000000
--- a/javatests/dagger/grpc/functional/server/FriendlyBarista.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import static java.util.Collections.singletonList;
-
-import com.google.protos.test.BaristaGrpc;
-import com.google.protos.test.BaristaGrpc.BaristaImplBase;
-import com.google.protos.test.CoffeeService.CoffeeRequest;
-import com.google.protos.test.CoffeeService.CoffeeResponse;
-import com.google.protos.test.CoffeeService.CoffeeType;
-import dagger.grpc.server.GrpcService;
-import io.grpc.stub.StreamObserver;
-import java.util.List;
-import javax.inject.Inject;
-
-@GrpcService(grpcClass = BaristaGrpc.class)
-class FriendlyBarista extends BaristaImplBase {
-
-  @Inject
-  FriendlyBarista() {}
-
-  @Override
-  public void unaryGetCoffee(
-      CoffeeRequest request, StreamObserver<CoffeeResponse> responseObserver) {
-    responseObserver.onNext(response("Here you go!", request.getTypeList()));
-    responseObserver.onCompleted();
-  }
-
-  @Override
-  public StreamObserver<CoffeeRequest> clientStreamingGetCoffee(
-      final StreamObserver<CoffeeResponse> responseObserver) {
-    return new StreamObserver<CoffeeRequest>() {
-
-      private final CoffeeResponse.Builder response = CoffeeResponse.newBuilder();
-
-      @Override
-      public void onNext(CoffeeRequest value) {
-        response.addAllCup(value.getTypeList());
-      }
-
-      @Override
-      public void onError(Throwable t) {}
-
-      @Override
-      public void onCompleted() {
-        response.setMessage("All yours!");
-        responseObserver.onNext(response.build());
-        responseObserver.onCompleted();
-      }
-    };
-  }
-
-  @Override
-  public void serverStreamingGetCoffee(
-      CoffeeRequest request, StreamObserver<CoffeeResponse> responseObserver) {
-    for (CoffeeType type : request.getTypeList()) {
-      responseObserver.onNext(response("Here's a " + type, singletonList(type)));
-    }
-    responseObserver.onCompleted();
-  }
-
-  @Override
-  public StreamObserver<CoffeeRequest> bidiStreamingGetCoffee(
-      final StreamObserver<CoffeeResponse> responseObserver) {
-    return new StreamObserver<CoffeeRequest>() {
-
-      private int responses;
-
-      @Override
-      public void onNext(CoffeeRequest value) {
-        responseObserver.onNext(response("Enjoy!", value.getTypeList()));
-        if (responses++ > 10) {
-          responseObserver.onNext(CoffeeResponse.newBuilder().setMessage("We're done.").build());
-          responseObserver.onCompleted();
-        }
-      }
-
-      @Override
-      public void onError(Throwable t) {}
-
-      @Override
-      public void onCompleted() {
-        responseObserver.onCompleted();
-      }
-    };
-  }
-
-  private CoffeeResponse response(String message, List<CoffeeType> types) {
-    return CoffeeResponse.newBuilder().addAllCup(types).setMessage(message).build();
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/VerifyInterceptor.java b/javatests/dagger/grpc/functional/server/VerifyInterceptor.java
deleted file mode 100644
index 99ecedb..0000000
--- a/javatests/dagger/grpc/functional/server/VerifyInterceptor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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.grpc.functional.server;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.protos.test.BaristaGrpc;
-import io.grpc.MethodDescriptor;
-import java.lang.annotation.Retention;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-final class VerifyInterceptor implements TestRule {
-
-  @Retention(RUNTIME)
-  @interface MethodName {
-    String value();
-  }
-
-  private final CoffeeServerResource coffeeServer;
-
-  VerifyInterceptor(CoffeeServerResource coffeeServer) {
-    this.coffeeServer = coffeeServer;
-  }
-
-  @Override
-  public Statement apply(final Statement base, Description description) {
-    MethodName annotation = description.getAnnotation(MethodName.class);
-    if (annotation == null) {
-      return base;
-    }
-    final String fullMethodName =
-        MethodDescriptor.generateFullMethodName(BaristaGrpc.SERVICE_NAME, annotation.value());
-    return new Statement() {
-      @Override
-      public void evaluate() throws Throwable {
-        int calls = coffeeServer.methodCount(fullMethodName);
-        base.evaluate();
-        assertWithMessage("Calls to %s", fullMethodName)
-            .that(coffeeServer.methodCount(fullMethodName))
-            .isEqualTo(calls + 1);
-      }
-    };
-  }
-}
diff --git a/javatests/dagger/grpc/functional/server/coffee_service.proto b/javatests/dagger/grpc/functional/server/coffee_service.proto
deleted file mode 100644
index a14c794..0000000
--- a/javatests/dagger/grpc/functional/server/coffee_service.proto
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2016 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.
-
-syntax = "proto3";
-
-package test;
-
-enum CoffeeType {
-  UNKNOWN = 0;
-  DRIP = 1;
-  POUR_OVER = 2;
-  ESPRESSO = 3;
-  AMERICANO = 4;
-  LATTE = 5;
-}
-
-message CoffeeRequest {
-  repeated CoffeeType type = 1;
-}
-
-message CoffeeResponse {
-  repeated CoffeeType cup = 1;
-  string message = 2;
-}
-
-service Barista {
-  rpc UnaryGetCoffee(CoffeeRequest) returns (CoffeeResponse) {
-  }
-
-  rpc ClientStreamingGetCoffee(stream CoffeeRequest) returns (CoffeeResponse) {
-  }
-
-  rpc ServerStreamingGetCoffee(CoffeeRequest) returns (stream CoffeeResponse) {
-  }
-
-  rpc BidiStreamingGetCoffee(stream CoffeeRequest)
-      returns (stream CoffeeResponse) {
-  }
-}
diff --git a/javatests/dagger/internal/DoubleCheckTest.java b/javatests/dagger/internal/DoubleCheckTest.java
deleted file mode 100644
index e36c1bc..0000000
--- a/javatests/dagger/internal/DoubleCheckTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2016 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;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Uninterruptibles;
-import dagger.Lazy;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DoubleCheckTest {
-  @Test
-  public void provider_nullPointerException() {
-    try {
-      DoubleCheck.provider(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test
-  public void lazy_nullPointerException() {
-    try {
-      DoubleCheck.lazy(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static final Provider<Object> DOUBLE_CHECK_OBJECT_PROVIDER =
-      DoubleCheck.provider(Object::new);
-
-  @Test
-  public void doubleWrapping_provider() {
-    assertThat(DoubleCheck.provider(DOUBLE_CHECK_OBJECT_PROVIDER))
-        .isSameInstanceAs(DOUBLE_CHECK_OBJECT_PROVIDER);
-  }
-
-  @Test
-  public void doubleWrapping_lazy() {
-    assertThat(DoubleCheck.lazy(DOUBLE_CHECK_OBJECT_PROVIDER))
-        .isSameInstanceAs(DOUBLE_CHECK_OBJECT_PROVIDER);
-  }
-
-  @Test
-  public void get() throws Exception {
-    int numThreads = 10;
-    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
-
-    final CountDownLatch latch = new CountDownLatch(numThreads);
-    LatchedProvider provider = new LatchedProvider(latch);
-    final Lazy<Object> lazy = DoubleCheck.lazy(provider);
-
-    List<Callable<Object>> tasks = Lists.newArrayListWithCapacity(numThreads);
-    for (int i = 0; i < numThreads; i++) {
-      tasks.add(
-          () -> {
-            latch.countDown();
-            return lazy.get();
-          });
-    }
-
-    List<Future<Object>> futures = executor.invokeAll(tasks);
-
-    assertThat(provider.provisions.get()).isEqualTo(1);
-    Set<Object> results = Sets.newIdentityHashSet();
-    for (Future<Object> future : futures) {
-      results.add(future.get());
-    }
-    assertThat(results).hasSize(1);
-  }
-
-  private static class LatchedProvider implements Provider<Object> {
-    final AtomicInteger provisions;
-    final CountDownLatch latch;
-
-    LatchedProvider(CountDownLatch latch) {
-      this.latch = latch;
-      this.provisions = new AtomicInteger();
-    }
-
-    @Override
-    public Object get() {
-      if (latch != null) {
-        Uninterruptibles.awaitUninterruptibly(latch);
-      }
-      provisions.incrementAndGet();
-      return new Object();
-    }
-  }
-
-  @Test public void reentranceWithoutCondition_throwsStackOverflow() {
-    final AtomicReference<Provider<Object>> doubleCheckReference =
-        new AtomicReference<>();
-    Provider<Object> doubleCheck = DoubleCheck.provider(() -> doubleCheckReference.get().get());
-    doubleCheckReference.set(doubleCheck);
-    try {
-      doubleCheck.get();
-      fail();
-    } catch (StackOverflowError expected) {}
-  }
-
-  @Test public void reentranceReturningSameInstance() {
-    final AtomicReference<Provider<Object>> doubleCheckReference =
-        new AtomicReference<>();
-    final AtomicInteger invocationCount = new AtomicInteger();
-    final Object object = new Object();
-    Provider<Object> doubleCheck = DoubleCheck.provider(() -> {
-        if (invocationCount.incrementAndGet() == 1) {
-         doubleCheckReference.get().get();
-       }
-       return object;
-     });
-    doubleCheckReference.set(doubleCheck);
-    assertThat(doubleCheck.get()).isSameInstanceAs(object);
-  }
-
-  @Test public void reentranceReturningDifferentInstances_throwsIllegalStateException() {
-    final AtomicReference<Provider<Object>> doubleCheckReference =
-        new AtomicReference<>();
-    final AtomicInteger invocationCount = new AtomicInteger();
-    Provider<Object> doubleCheck = DoubleCheck.provider(() -> {
-       if (invocationCount.incrementAndGet() == 1) {
-         doubleCheckReference.get().get();
-       }
-       return new Object();
-     });
-    doubleCheckReference.set(doubleCheck);
-    try {
-      doubleCheck.get();
-      fail();
-    } catch (IllegalStateException expected) {}
-  }
-
-  @Test
-  public void instanceFactoryAsLazyDoesNotWrap() {
-    Factory<Object> factory = InstanceFactory.create(new Object());
-    assertThat(DoubleCheck.lazy(factory)).isSameInstanceAs(factory);
-  }
-}
diff --git a/javatests/dagger/internal/InstanceFactoryTest.java b/javatests/dagger/internal/InstanceFactoryTest.java
deleted file mode 100644
index 82b66e6..0000000
--- a/javatests/dagger/internal/InstanceFactoryTest.java
+++ /dev/null
@@ -1,43 +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;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class InstanceFactoryTest {
-  @Test public void instanceFactory() {
-    Object instance = new Object();
-    Factory<Object> factory = InstanceFactory.create(instance);
-    assertThat(factory.get()).isEqualTo(instance);
-    assertThat(factory.get()).isEqualTo(instance);
-    assertThat(factory.get()).isEqualTo(instance);
-  }
-
-  @Test public void create_throwsNullPointerException() {
-    try {
-      InstanceFactory.create(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/internal/MapProviderFactoryTest.java b/javatests/dagger/internal/MapProviderFactoryTest.java
deleted file mode 100644
index 5598ff2..0000000
--- a/javatests/dagger/internal/MapProviderFactoryTest.java
+++ /dev/null
@@ -1,80 +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;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Provider;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-@SuppressWarnings("unchecked")
-public class MapProviderFactoryTest {
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Test
-  public void nullKey() {
-    thrown.expect(NullPointerException.class);
-    MapProviderFactory.<String, Integer>builder(1).put(null, incrementingIntegerProvider(1));
-  }
-
-  @Test
-  public void nullValue() {
-    thrown.expect(NullPointerException.class);
-    MapProviderFactory.<String, Integer>builder(1).put("Hello", null);
-  }
-
-  @Test
-  public void iterationOrder() {
-    Provider<Integer> p1 = incrementingIntegerProvider(10);
-    Provider<Integer> p2 = incrementingIntegerProvider(20);
-    Provider<Integer> p3 = incrementingIntegerProvider(30);
-    Provider<Integer> p4 = incrementingIntegerProvider(40);
-    Provider<Integer> p5 = incrementingIntegerProvider(50);
-
-    Factory<Map<String, Provider<Integer>>> factory = MapProviderFactory
-        .<String, Integer>builder(4)
-        .put("two", p2)
-        .put("one", p1)
-        .put("three", p3)
-        .put("one", p5)
-        .put("four", p4)
-        .build();
-
-    Map<String, Provider<Integer>> expectedMap = new LinkedHashMap<>();
-    expectedMap.put("two", p2);
-    expectedMap.put("one", p1);
-    expectedMap.put("three", p3);
-    expectedMap.put("one", p5);
-    expectedMap.put("four", p4);
-    assertThat(factory.get().entrySet())
-        .containsExactlyElementsIn(expectedMap.entrySet())
-        .inOrder();
-  }
-
-  private static Provider<Integer> incrementingIntegerProvider(int seed) {
-    return new AtomicInteger(seed)::getAndIncrement;
-  }
-}
diff --git a/javatests/dagger/internal/SetBuilderTest.java b/javatests/dagger/internal/SetBuilderTest.java
deleted file mode 100644
index ac78312..0000000
--- a/javatests/dagger/internal/SetBuilderTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import static org.junit.Assert.fail;
-
-import java.util.Arrays;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SetBuilderTest {
-  private SetBuilder<String> setBuilder;
-
-  @Before
-  public void setUp() {
-    setBuilder = SetBuilder.newSetBuilder(1);
-  }
-
-  @Test
-  public void addNull() {
-    try {
-      setBuilder.add(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test
-  public void addNullCollection() {
-    try {
-      setBuilder.addAll(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test
-  public void addNullElement() {
-    try {
-      setBuilder.addAll(Arrays.asList("hello", null, "world"));
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-}
diff --git a/javatests/dagger/internal/SetFactoryTest.java b/javatests/dagger/internal/SetFactoryTest.java
deleted file mode 100644
index 0032578..0000000
--- a/javatests/dagger/internal/SetFactoryTest.java
+++ /dev/null
@@ -1,86 +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;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Provider;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-@SuppressWarnings("unchecked")
-public class SetFactoryTest {
-  @Rule public ExpectedException thrown = ExpectedException.none();
-
-  @Test
-  public void providerReturnsNull() {
-    Factory<Set<Integer>> factory =
-        SetFactory.<Integer>builder(0, 1).addCollectionProvider(() -> null).build();
-    thrown.expect(NullPointerException.class);
-    factory.get();
-  }
-
-  @Test
-  public void providerReturnsNullSet() {
-    Factory<Set<Integer>> factory =
-        SetFactory.<Integer>builder(1, 0).addProvider(() -> null).build();
-    thrown.expect(NullPointerException.class);
-    factory.get();
-  }
-
-  @Test
-  public void providerReturnsSetWithNullElement() {
-    Set<Integer> set = new LinkedHashSet<>(Arrays.asList(1, null, 3));
-    Factory<Set<Integer>> factory =
-        SetFactory.<Integer>builder(0, 1).addCollectionProvider(() -> set).build();
-    thrown.expect(NullPointerException.class);
-    factory.get();
-  }
-
-  @Test
-  public void invokesProvidersEveryTime() {
-    Factory<Set<Integer>> factory =
-        SetFactory.<Integer>builder(2, 2)
-            .addProvider(incrementingIntegerProvider(0))
-            .addProvider(incrementingIntegerProvider(10))
-            .addCollectionProvider(incrementingIntegerSetProvider(20))
-            .addCollectionProvider(incrementingIntegerSetProvider(30))
-            .build();
-    assertThat(factory.get()).containsExactly(0, 10, 20, 21, 30, 31);
-    assertThat(factory.get()).containsExactly(1, 11, 22, 23, 32, 33);
-    assertThat(factory.get()).containsExactly(2, 12, 24, 25, 34, 35);
-  }
-
-  private static Provider<Integer> incrementingIntegerProvider(int seed) {
-    final AtomicInteger value = new AtomicInteger(seed);
-    return value::getAndIncrement;
-  }
-
-  private static Provider<Set<Integer>> incrementingIntegerSetProvider(int seed) {
-    final AtomicInteger value = new AtomicInteger(seed);
-    return () -> ImmutableSet.of(value.getAndIncrement(), value.getAndIncrement());
-  }
-}
diff --git a/javatests/dagger/internal/SingleCheckTest.java b/javatests/dagger/internal/SingleCheckTest.java
deleted file mode 100644
index 0c043fd..0000000
--- a/javatests/dagger/internal/SingleCheckTest.java
+++ /dev/null
@@ -1,45 +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;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link SingleCheck}.
- */
-@RunWith(JUnit4.class)
-public class SingleCheckTest {
-  @Test(expected = NullPointerException.class)
-  public void create_nullPointerException() {
-    SingleCheck.provider(null);
-  }
-
-  @Test
-  public void get() {
-    AtomicInteger integer = new AtomicInteger();
-    Provider<Integer> provider = SingleCheck.provider(integer::getAndIncrement);
-    assertThat(provider.get()).isEqualTo(0);
-    assertThat(provider.get()).isEqualTo(0);
-    assertThat(provider.get()).isEqualTo(0);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsMultibindingsTest.java b/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsMultibindingsTest.java
deleted file mode 100644
index bb967b1..0000000
--- a/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsMultibindingsTest.java
+++ /dev/null
@@ -1,2838 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.AHEAD_OF_TIME_SUBCOMPONENTS_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.CLASS_PATH_WITHOUT_GUAVA_OPTION;
-import static dagger.internal.codegen.Compilers.compilerWithOptions;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.GENERATION_OPTIONS_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class AheadOfTimeSubcomponentsMultibindingsTest {
-  @Test
-  public void setMultibindings_contributionsInLeaf() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<InLeaf> contributionsInLeaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InLeaf provideInLeaf() {",
-            "    return new InLeaf();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<InLeaf> contributionsInLeaf() {",
-            "    return ImmutableSet.<InLeaf>of(",
-            "        LeafModule_ProvideInLeafFactory.provideInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-  }
-
-  @Test
-  public void setMultibindings_contributionsInAncestorOnly() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Set<InAncestor> contributionsInAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Set<InAncestor> contributionsInAncestor();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @ElementsIntoSet",
-            "  static Set<InAncestor> provideInAncestors() {",
-            "    return ImmutableSet.of(new InAncestor(), new InAncestor());",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<InAncestor> contributionsInAncestor() {",
-            "      return ImmutableSet.<InAncestor>copyOf(",
-            "          AncestorModule_ProvideInAncestorsFactory.provideInAncestors());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void setMultibindings_contributionsInLeafAndAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<InEachSubcomponent> contributionsInEachSubcomponent();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InEachSubcomponent provideInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InEachSubcomponent provideAnotherInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "    return ImmutableSet.<InEachSubcomponent>of(",
-            "        LeafModule_ProvideInLeafFactory.provideInLeaf(),",
-            "        LeafModule_ProvideAnotherInLeafFactory.provideAnotherInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @ElementsIntoSet",
-            "  static Set<InEachSubcomponent> provideInAncestor() {",
-            "    return ImmutableSet.of(new InEachSubcomponent(), new InEachSubcomponent());",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "      return ImmutableSet.<InEachSubcomponent>builderWithExpectedSize(3)",
-            "          .addAll(AncestorModule_ProvideInAncestorFactory.provideInAncestor())",
-            "          .addAll(super.contributionsInEachSubcomponent())",
-            "          .build();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void setMultibindings_contributionsInLeafAndGrandAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InLeafAndGrandAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InLeafAndGrandAncestor provideInLeaf() {",
-            "    return new InLeafAndGrandAncestor();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InLeafAndGrandAncestor provideAnotherInLeaf() {",
-            "    return new InLeafAndGrandAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {",
-            "    return ImmutableSet.<InLeafAndGrandAncestor>of(",
-            "        LeafModule_ProvideInLeafFactory.provideInLeaf(),",
-            "        LeafModule_ProvideAnotherInLeafFactory.provideAnotherInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = GrandAncestorModule.class)",
-            "interface GrandAncestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestorModule",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class GrandAncestorModule {",
-            "  @Provides",
-            "  @ElementsIntoSet",
-            "  static Set<InLeafAndGrandAncestor> provideInGrandAncestor() {",
-            "    return ImmutableSet.of(new InLeafAndGrandAncestor(),",
-            "        new InLeafAndGrandAncestor());",
-            "  }",
-            "}"));
-    JavaFileObject generatedGrandAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerGrandAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGrandAncestor implements GrandAncestor {",
-            "  protected DaggerGrandAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {",
-            "      return ImmutableSet.<InLeafAndGrandAncestor>builderWithExpectedSize(3)",
-            "          .addAll(GrandAncestorModule_ProvideInGrandAncestorFactory",
-            "              .provideInGrandAncestor())",
-            "          .addAll(super.contributionsInLeafAndGrandAncestor())",
-            "          .build();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGrandAncestor")
-        .hasSourceEquivalentTo(generatedGrandAncestor);
-  }
-
-  @Test
-  public void setMultibindings_nonComponentMethodDependency() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(
-        filesToCompile, "InAllSubcomponents", "RequresInAllSubcomponentsSet");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  RequresInAllSubcomponentsSet requiresNonComponentMethod();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InAllSubcomponents provideInAllSubcomponents() {",
-            "    return new InAllSubcomponents();",
-            "  }",
-            "",
-            "  @Provides",
-            "  static RequresInAllSubcomponentsSet providesRequresInAllSubcomponentsSet(",
-            "      Set<InAllSubcomponents> inAllSubcomponents) {",
-            "    return new RequresInAllSubcomponentsSet();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public RequresInAllSubcomponentsSet requiresNonComponentMethod() {",
-            "    return LeafModule_ProvidesRequresInAllSubcomponentsSetFactory",
-            "        .providesRequresInAllSubcomponentsSet(getSetOfInAllSubcomponents());",
-            "  }",
-            "",
-            "  protected Set getSetOfInAllSubcomponents() {",
-            "    return ImmutableSet.<InAllSubcomponents>of(",
-            "        LeafModule_ProvideInAllSubcomponentsFactory",
-            "            .provideInAllSubcomponents());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InAllSubcomponents provideInAllSubcomponents() {",
-            "      return new InAllSubcomponents();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected Set getSetOfInAllSubcomponents() {",
-            "      return ImmutableSet.<InAllSubcomponents>builderWithExpectedSize(2)",
-            "          .add(AncestorModule_ProvideInAllSubcomponentsFactory",
-            "              .provideInAllSubcomponents())",
-            "          .addAll(super.getSetOfInAllSubcomponents())",
-            "          .build();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void setMultibindings_newSubclass() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InAncestor", "RequiresInAncestorSet");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  RequiresInAncestorSet missingWithSetDependency();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract RequiresInAncestorSet missingWithSetDependency();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "",
-            "  @Provides",
-            "  static RequiresInAncestorSet provideRequiresInAncestorSet(",
-            "      Set<InAncestor> inAncestors) {",
-            "    return new RequiresInAncestorSet();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InAncestor provideInAncestor() {",
-            "    return new InAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  private RequiresInAncestorSet getRequiresInAncestorSet() {",
-            "    return AncestorModule_ProvideRequiresInAncestorSetFactory",
-            "        .provideRequiresInAncestorSet(getSetOfInAncestor());",
-            "  }",
-            "",
-            "  protected Set getSetOfInAncestor() {",
-            "    return ImmutableSet.<InAncestor>of(",
-            "        AncestorModule_ProvideInAncestorFactory.provideInAncestor());",
-            "  }",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public final RequiresInAncestorSet missingWithSetDependency() {",
-            "      return DaggerAncestor.this.getRequiresInAncestorSet();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void setMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(
-        filesToCompile, "Multibound", "MissingInLeaf_WillDependOnFrameworkInstance");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<Multibound> instance();",
-            "  MissingInLeaf_WillDependOnFrameworkInstance willDependOnFrameworkInstance();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Multibound contribution() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<Multibound> instance() {",
-            "    return ImmutableSet.<Multibound>of(",
-            "        LeafModule_ContributionFactory.contribution());",
-            "  }",
-            "",
-            "  @Override",
-            "  public abstract MissingInLeaf_WillDependOnFrameworkInstance",
-            "      willDependOnFrameworkInstance();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static MissingInLeaf_WillDependOnFrameworkInstance providedInAncestor(",
-            "      Provider<Set<Multibound>> frameworkInstance) {",
-            "    return null;",
-            "  }",
-            "",
-            "  @Multibinds Set<Multibound> multibinds();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Set<Multibound>> setOfMultiboundProvider;",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    protected void configureInitialization() { ",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() { ",
-            "      this.setOfMultiboundProvider =",
-            "          SetFactory.<Multibound>builder(1, 0)",
-            "              .addProvider(LeafModule_ContributionFactory.create())",
-            "              .build();",
-            "    }",
-            "",
-            "    protected Provider getSetOfMultiboundProvider() {",
-            "      return setOfMultiboundProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    public final MissingInLeaf_WillDependOnFrameworkInstance ",
-            "        willDependOnFrameworkInstance() {",
-            "      return AncestorModule_ProvidedInAncestorFactory.providedInAncestor(",
-            "          getSetOfMultiboundProvider());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void missingMultibindingInLeaf_onlyContributionsInAncestor_notReModifiedInRoot() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Set<Object> set();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Set<Object> set();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Object onlyContribution() {",
-            "    return new Object();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<Object> set() {",
-            "      return ImmutableSet.<Object>of(",
-            "          AncestorModule_OnlyContributionFactory.onlyContribution());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf leaf() {",
-            "      return new LeafImpl();",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private LeafImpl() {}",
-            // This tests a regression case where Dagger used to reimplement Leaf.set(), even though
-            // there were no new contributions, because the state change from missing -> 
-            // multibinding wasn't properly recorded
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void setMultibindings_contributionsInLeafAndAncestor_frameworkInstances() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InEachSubcomponent provideInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static InEachSubcomponent provideAnotherInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Provider<Set<InEachSubcomponent>> setOfInEachSubcomponentProvider;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.setOfInEachSubcomponentProvider =",
-            "        SetFactory.<InEachSubcomponent>builder(2, 0)",
-            "            .addProvider(LeafModule_ProvideInLeafFactory.create())",
-            "            .addProvider(LeafModule_ProvideAnotherInLeafFactory.create())",
-            "            .build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent() {",
-            "    return setOfInEachSubcomponentProvider;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @ElementsIntoSet",
-            "  static Set<InEachSubcomponent> provideInAncestor() {",
-            "    return ImmutableSet.of(new InEachSubcomponent(), new InEachSubcomponent());",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Set<InEachSubcomponent>> setOfInEachSubcomponentProvider = ",
-            "        new DelegateFactory<>();",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected void configureInitialization() {",
-            "      super.configureInitialization();",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      DelegateFactory.setDelegate(",
-            "          setOfInEachSubcomponentProvider,",
-            "          SetFactory.<InEachSubcomponent>builder(0, 2)",
-            "              .addCollectionProvider(super.contributionsInEachSubcomponent())",
-            "              .addCollectionProvider(",
-            "                  AncestorModule_ProvideInAncestorFactory.create())",
-            "              .build());",
-            "    }",
-            "",
-            "    @Override",
-            "    public Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent() {",
-            "      return setOfInEachSubcomponentProvider;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInLeaf() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<String, InLeaf> contributionsInLeaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"leafmodule\")",
-            "  static InLeaf provideInLeaf() {",
-            "    return new InLeaf();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<String, InLeaf> contributionsInLeaf() {",
-            "    return ImmutableMap.<String, InLeaf>of(",
-            "        \"leafmodule\",",
-            "        LeafModule_ProvideInLeafFactory.provideInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInAncestorOnly() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Map<String, InAncestor> contributionsInAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Map<String, InAncestor> contributionsInAncestor();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"ancestormodule\")",
-            "  static InAncestor provideInAncestor() {",
-            "    return new InAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Map<String, InAncestor> contributionsInAncestor() {",
-            "      return ImmutableMap.<String, InAncestor>of(\"ancestormodule\",",
-            "          AncestorModule_ProvideInAncestorFactory.provideInAncestor());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInLeafAndAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<String, InEachSubcomponent> contributionsInEachSubcomponent();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"leafmodule\")",
-            "  static InEachSubcomponent provideInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "    return ImmutableMap.<String, InEachSubcomponent>of(",
-            "        \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"ancestormodule\")",
-            "  static InEachSubcomponent provideInAncestor() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "      return ImmutableMap.<String, InEachSubcomponent>builderWithExpectedSize(2)",
-            "          .put(\"ancestormodule\",",
-            "              AncestorModule_ProvideInAncestorFactory.provideInAncestor())",
-            "          .putAll(super.contributionsInEachSubcomponent())",
-            "          .build();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInLeafAndAncestor_frameworkInstance() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Provider<Map<String, InEachSubcomponent>> contributionsInEachSubcomponent();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"leafmodule\")",
-            "  static InEachSubcomponent provideInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapFactory;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Provider<Map<String, InEachSubcomponent>> ",
-            "    mapOfStringAndInEachSubcomponentProvider;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.mapOfStringAndInEachSubcomponentProvider =",
-            "        MapFactory.<String, InEachSubcomponent>builder(1)",
-            "            .put(\"leafmodule\", LeafModule_ProvideInLeafFactory.create())",
-            "            .build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<Map<String, InEachSubcomponent>> ",
-            "      contributionsInEachSubcomponent() {",
-            "    return mapOfStringAndInEachSubcomponentProvider;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"ancestormodule\")",
-            "  static InEachSubcomponent provideInAncestor() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapFactory;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Map<String, InEachSubcomponent>> ",
-            "      mapOfStringAndInEachSubcomponentProvider = new DelegateFactory<>();",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected void configureInitialization() { ",
-            "      super.configureInitialization();",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() { ",
-            "      DelegateFactory.setDelegate(",
-            "          mapOfStringAndInEachSubcomponentProvider,",
-            "          MapFactory.<String, InEachSubcomponent>builder(2)",
-            "              .putAll(super.contributionsInEachSubcomponent())",
-            "              .put(",
-            "                  \"ancestormodule\",",
-            "                  AncestorModule_ProvideInAncestorFactory.create())",
-            "              .build());",
-            "    }",
-            "",
-            "    @Override",
-            "    public Provider<Map<String, InEachSubcomponent>> ",
-            "        contributionsInEachSubcomponent() {",
-            "      return mapOfStringAndInEachSubcomponentProvider;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInLeafAndGrandAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InLeafAndGrandAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<String, InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"leafmodule\")",
-            "  static InLeafAndGrandAncestor provideInLeaf() {",
-            "    return new InLeafAndGrandAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<String, InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {",
-            "    return ImmutableMap.<String, InLeafAndGrandAncestor>of(",
-            "        \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GrandAncestorModule.class)",
-            "interface GrandAncestor {",
-            "  Ancestor ancestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class GrandAncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"grandancestormodule\")",
-            "  static InLeafAndGrandAncestor provideInGrandAncestor() {",
-            "    return new InLeafAndGrandAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedGrandAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerGrandAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGrandAncestor implements GrandAncestor {",
-            "  protected DaggerGrandAncestor() {}",
-            "",
-            "  protected abstract class AncestorImpl extends DaggerAncestor {",
-            "    protected AncestorImpl() {}",
-            "",
-            "    protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      protected LeafImpl() {}",
-            "",
-            "      @Override",
-            "      public Map<String, InLeafAndGrandAncestor>",
-            "          contributionsInLeafAndGrandAncestor() {",
-            "        return",
-            "            ImmutableMap.<String, InLeafAndGrandAncestor>builderWithExpectedSize(2)",
-            "                .put(\"grandancestormodule\",",
-            "                    GrandAncestorModule_ProvideInGrandAncestorFactory",
-            "                        .provideInGrandAncestor())",
-            "                .putAll(super.contributionsInLeafAndGrandAncestor())",
-            "                .build();",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGrandAncestor")
-        .hasSourceEquivalentTo(generatedGrandAncestor);
-  }
-
-  @Test
-  public void mapMultibindings_contributionsInLeafAndAncestorWithoutGuava() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<String, InEachSubcomponent> contributionsInEachSubcomponent();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"leafmodule\")",
-            "  static InEachSubcomponent provideInLeaf() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Collections;",
-            "import java.util.Map",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "    return Collections.<String, InEachSubcomponent>singletonMap(",
-            "        \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());",
-            "  }",
-            "}");
-    Compilation compilation = compileWithoutGuava(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @StringKey(\"ancestormodule\")",
-            "  static InEachSubcomponent provideInAncestor() {",
-            "    return new InEachSubcomponent();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapBuilder;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {",
-            "      return MapBuilder.<String, InEachSubcomponent>newMapBuilder(2)",
-            "          .put(\"ancestormodule\",",
-            "              AncestorModule_ProvideInAncestorFactory.provideInAncestor())",
-            "          .putAll(super.contributionsInEachSubcomponent())",
-            "          .build();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compileWithoutGuava(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void mapMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(
-        filesToCompile, "Multibound", "MissingInLeaf_WillDependOnFrameworkInstance");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<Integer, Multibound> instance();",
-            "  MissingInLeaf_WillDependOnFrameworkInstance willDependOnFrameworkInstance();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @IntKey(111)",
-            "  static Multibound contribution() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<Integer, Multibound> instance() {",
-            "    return ImmutableMap.<Integer, Multibound>of(",
-            "        111, LeafModule_ContributionFactory.contribution());",
-            "  }",
-            "",
-            "  @Override",
-            "  public abstract MissingInLeaf_WillDependOnFrameworkInstance",
-            "      willDependOnFrameworkInstance();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static MissingInLeaf_WillDependOnFrameworkInstance providedInAncestor(",
-            "      Provider<Map<Integer, Multibound>> frameworkInstance) {",
-            "    return null;",
-            "  }",
-            "",
-            "  @Multibinds Map<Integer, Multibound> multibinds();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapFactory;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Map<Integer, Multibound>> mapOfIntegerAndMultiboundProvider;",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    protected void configureInitialization() { ",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() { ",
-            "      this.mapOfIntegerAndMultiboundProvider =",
-            "          MapFactory.<Integer, Multibound>builder(1)",
-            "              .put(111, LeafModule_ContributionFactory.create())",
-            "              .build();",
-            "    }",
-            "",
-            "    protected Provider getMapOfIntegerAndMultiboundProvider() {",
-            "      return mapOfIntegerAndMultiboundProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    public final MissingInLeaf_WillDependOnFrameworkInstance ",
-            "        willDependOnFrameworkInstance() {",
-            "      return AncestorModule_ProvidedInAncestorFactory.providedInAncestor(",
-            "          getMapOfIntegerAndMultiboundProvider());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void emptyMultibinds_set() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Multibound");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Multibinds",
-            "  Set<Multibound> set();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<Multibound> set();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<Multibound> set() {",
-            "    return ImmutableSet.<Multibound>of();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Multibound fromAncestor() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<Multibound> set() {",
-            "      return ImmutableSet.<Multibound>of(",
-            "          AncestorModule_FromAncestorFactory.fromAncestor());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void emptyMultibinds_set_frameworkInstance() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Multibound");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Multibinds",
-            "  Set<Multibound> set();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Provider<Set<Multibound>> set();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Provider<Set<Multibound>> set() {",
-            "    return SetFactory.<Multibound>empty();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Multibound fromAncestor() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Set<Multibound>> setOfMultiboundProvider =",
-            "        new DelegateFactory<>();",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    protected void configureInitialization() {",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      DelegateFactory.setDelegate(",
-            "          setOfMultiboundProvider,",
-            "          SetFactory.<Multibound>builder(1, 0)",
-            "              .addProvider(AncestorModule_FromAncestorFactory.create())",
-            "              .build());",
-            "    }",
-            "",
-            "    @Override",
-            "    public Provider<Set<Multibound>> set() {",
-            "      return setOfMultiboundProvider;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void emptyMultibinds_map() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Multibound");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Multibinds",
-            "  Map<Integer, Multibound> map();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Map<Integer, Multibound> map();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Map<Integer, Multibound> map() {",
-            "    return ImmutableMap.<Integer, Multibound>of();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @IntKey(111)",
-            "  static Multibound fromAncestor() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableMap;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Map<Integer, Multibound> map() {",
-            "      return ImmutableMap.<Integer, Multibound>of(",
-            "          111, AncestorModule_FromAncestorFactory.fromAncestor());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void emptyMultibinds_map_frameworkInstance() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Multibound");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Multibinds",
-            "  Map<Integer, Multibound> map();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Provider<Map<Integer, Multibound>> map();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapFactory;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Provider<Map<Integer, Multibound>> map() {",
-            "    return MapFactory.<Integer, Multibound>emptyMapProvider();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  @IntoMap",
-            "  @IntKey(111)",
-            "  static Multibound fromAncestor() {",
-            "    return new Multibound();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.MapFactory;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Map<Integer, Multibound>> mapOfIntegerAndMultiboundProvider =",
-            "        new DelegateFactory<>()",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    protected void configureInitialization() {",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      DelegateFactory.setDelegate(",
-            "          mapOfIntegerAndMultiboundProvider,",
-            "          MapFactory.<Integer, Multibound>builder(1)",
-            "              .put(111, AncestorModule_FromAncestorFactory.create())",
-            "              .build());",
-            "    }",
-            "",
-            "    @Override",
-            "    public Provider<Map<Integer, Multibound>> map() {",
-            "      return mapOfIntegerAndMultiboundProvider;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void bindsMissingDep_Multibindings() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Binds",
-            "  @IntoSet",
-            "  CharSequence bindsMultibindingWithMissingDep(String string);",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Set<CharSequence> set();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Set<CharSequence> set() {",
-            "    return ImmutableSet.<CharSequence>of(getBindsMultibindingWithMissingDep());",
-            "  }",
-            "",
-            // The expected output here is subtle: the Key of
-            // LeafModule.bindsMultibindingWithMissingDep() is Set<CharSequence>, but the binding
-            // method should only be returning an individual CharSequence. Otherwise the
-            // ImmutableSet factory method above will fail.
-            "  protected abstract CharSequence getBindsMultibindingWithMissingDep();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-  }
-
-  @Test
-  public void multibindingsAndFastInit() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "PackagePrivate");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.MultibindingModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "interface MultibindingModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  @LeafScope",
-            "  static PackagePrivate setContribution() {",
-            "    return new PackagePrivate();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoMap",
-            "  @IntKey(1)",
-            "  @LeafScope",
-            "  static PackagePrivate mapContribution() {",
-            "    return new PackagePrivate();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface LeafScope {}"),
-        JavaFileObjects.forSourceLines(
-            "test.UsesMultibindings",
-            "package test;",
-            "",
-            "import java.util.Map;",
-            "import java.util.Set;",
-            "import javax.inject.Inject;",
-            "",
-            "class UsesMultibindings {",
-            "  @Inject",
-            "  UsesMultibindings(Set<PackagePrivate> set, Map<Integer, PackagePrivate> map) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import java.util.Set;",
-            "",
-            "@LeafScope",
-            "@Subcomponent(modules = MultibindingModule.class)",
-            "interface Leaf {",
-            "  UsesMultibindings entryPoint();",
-            "}"));
-
-    Compilation compilation =
-        compilerWithOptions(AHEAD_OF_TIME_SUBCOMPONENTS_MODE, FAST_INIT_MODE)
-            .compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "@GenerationOptions(fastInit = true)",
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  private PackagePrivate getSetContribution() {",
-            "    Object local = setContribution;",
-            "    if (local instanceof MemoizedSentinel) {",
-            "      synchronized (local) {",
-            "        local = setContribution;",
-            "        if (local instanceof MemoizedSentinel) {",
-            "          local = MultibindingModule_SetContributionFactory.setContribution();",
-            "          setContribution = DoubleCheck.reentrantCheck(setContribution, local);",
-            "        }",
-            "      }",
-            "    }",
-            "    return (PackagePrivate) local;",
-            "  }",
-            "",
-            "  private PackagePrivate getMapContribution() {",
-            "    Object local = mapContribution;",
-            "    if (local instanceof MemoizedSentinel) {",
-            "      synchronized (local) {",
-            "        local = mapContribution;",
-            "        if (local instanceof MemoizedSentinel) {",
-            "          local = MultibindingModule_MapContributionFactory.mapContribution();",
-            "          mapContribution = DoubleCheck.reentrantCheck(mapContribution, local);",
-            "        }",
-            "      }",
-            "    }",
-            "    return (PackagePrivate) local;",
-            "  }",
-            "",
-            "  @Override",
-            "  public UsesMultibindings entryPoint() {",
-            "    return new UsesMultibindings(",
-            "        getSetOfPackagePrivate(), getMapOfIntegerAndPackagePrivate());",
-            "  }",
-            "",
-            "  protected Set getSetOfPackagePrivate() {",
-            "    return ImmutableSet.<PackagePrivate>of(getSetContribution());",
-            "  }",
-            "",
-            "  protected Map getMapOfIntegerAndPackagePrivate() {",
-            "    return ImmutableMap.<Integer, PackagePrivate>of(1, getMapContribution());",
-            "  }",
-            "}");
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-  }
-
-  // TODO(ronshapiro): remove copies from AheadOfTimeSubcomponents*Test classes
-  private void createSimplePackagePrivateClasses(
-      ImmutableList.Builder<JavaFileObject> filesBuilder, String... ancillaryClasses) {
-    for (String className : ancillaryClasses) {
-      filesBuilder.add(
-          JavaFileObjects.forSourceLines(
-              String.format("test.%s", className),
-              "package test;",
-              "",
-              String.format("class %s { }", className)));
-    }
-  }
-
-  private static Compilation compile(Iterable<JavaFileObject> files) {
-    return compilerWithOptions(AHEAD_OF_TIME_SUBCOMPONENTS_MODE).compile(files);
-  }
-
-  private static Compilation compileWithoutGuava(Iterable<JavaFileObject> files) {
-    return daggerCompiler()
-        .withOptions(
-            AHEAD_OF_TIME_SUBCOMPONENTS_MODE.javacopts().append(CLASS_PATH_WITHOUT_GUAVA_OPTION))
-        .compile(files);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsTest.java b/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsTest.java
deleted file mode 100644
index 1bd221a..0000000
--- a/javatests/dagger/internal/codegen/AheadOfTimeSubcomponentsTest.java
+++ /dev/null
@@ -1,5677 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.AHEAD_OF_TIME_SUBCOMPONENTS_MODE;
-import static dagger.internal.codegen.Compilers.compilerWithOptions;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.GENERATION_OPTIONS_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ObjectArrays;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class AheadOfTimeSubcomponentsTest {
-  private static final String PRUNED_METHOD_BODY =
-      "throw new UnsupportedOperationException(\"This binding is not part of the final binding "
-          + "graph. The key was requested by a binding that was believed to possibly be part of "
-          + "the graph, but is no longer requested. If this exception is thrown, it is the result "
-          + "of a Dagger bug.\");";
-
-  @Test
-  public void missingBindings_fromComponentMethod() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  MissingInLeaf missingFromComponentMethod();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract MissingInLeaf missingFromComponentMethod();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static MissingInLeaf satisfiedInAncestor() { return new MissingInLeaf(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public final MissingInLeaf missingFromComponentMethod() {",
-            "      return AncestorModule_SatisfiedInAncestorFactory.satisfiedInAncestor();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void missingBindings_dependsOnBindingWithMatchingComponentMethod() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  MissingInLeaf missingComponentMethod();",
-            "  DependsOnComponentMethod dependsOnComponentMethod();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.DependsOnComponentMethod",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class DependsOnComponentMethod {",
-            "  @Inject DependsOnComponentMethod(MissingInLeaf missingInLeaf) {}",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract MissingInLeaf missingComponentMethod();",
-            "",
-            "  @Override",
-            "  public DependsOnComponentMethod dependsOnComponentMethod() {",
-            "    return new DependsOnComponentMethod(missingComponentMethod());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-  }
-
-  @Test
-  public void missingBindings_dependsOnMissingBinding() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  DependsOnMissingBinding dependsOnMissingBinding();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.DependsOnMissingBinding",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class DependsOnMissingBinding {",
-            "  @Inject DependsOnMissingBinding(MissingInLeaf missing) {}",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public DependsOnMissingBinding dependsOnMissingBinding() {",
-            "    return new DependsOnMissingBinding((MissingInLeaf) getMissingInLeaf());",
-            "  }",
-            "",
-            "  protected abstract Object getMissingInLeaf();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static MissingInLeaf satisfiedInAncestor() { return new MissingInLeaf(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected final Object getMissingInLeaf() {",
-            "      return AncestorModule_SatisfiedInAncestorFactory.satisfiedInAncestor();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void missingBindings_satisfiedInGreatAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  DependsOnMissingBinding dependsOnMissingBinding();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.DependsOnMissingBinding",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class DependsOnMissingBinding {",
-            "  @Inject DependsOnMissingBinding(MissingInLeaf missing) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GreatAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = SatisfiesMissingBindingModule.class)",
-            "interface GreatAncestor {",
-            "  Ancestor ancestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.SatisfiesMissingBindingModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class SatisfiesMissingBindingModule {",
-            "  @Provides",
-            "  static MissingInLeaf satisfy() { return new MissingInLeaf(); }",
-            "}"));
-    // DaggerLeaf+DaggerAncestor generated types are ignored - they're not the focus of this test
-    // and are tested elsewhere
-    JavaFileObject generatedGreatAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGreatAncestor implements GreatAncestor {",
-            "  protected DaggerGreatAncestor() {}",
-            "",
-            "  protected abstract class AncestorImpl extends DaggerAncestor {",
-            "    protected AncestorImpl() {}",
-            "",
-            "    protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      protected LeafImpl() {}",
-            "",
-            "      @Override",
-            "      protected final Object getMissingInLeaf() {",
-            "        return SatisfiesMissingBindingModule_SatisfyFactory.satisfy();",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGreatAncestor")
-        .hasSourceEquivalentTo(generatedGreatAncestor);
-  }
-
-  @Test
-  public void moduleInstanceDependency() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = TestModule.class)",
-            "interface Leaf {",
-            "  String string();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class TestModule {",
-            "  @Provides String provideString() { return \"florp\"; }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public String string() {",
-            "    return TestModule_ProvideStringFactory.provideString(testModule());",
-            "  }",
-            "",
-            "  protected abstract TestModule testModule();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf leaf() {",
-            "      return new LeafImpl();",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private final TestModule testModule;",
-            "",
-            "      private LeafImpl() {",
-            "        this.testModule = new TestModule();",
-            "      }",
-            "",
-            "      @Override",
-            "      protected TestModule testModule() {",
-            "        return testModule;",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void moduleInstanceDependency_withModuleParams() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = TestModule.class)",
-            "interface Leaf {",
-            "  int getInt();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  private int i;",
-            "",
-            "  TestModule(int i) {}",
-            "",
-            "  @Provides int provideInt() {",
-            "    return i++;",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public int getInt() {",
-            "    return testModule().provideInt();",
-            "  }",
-            "",
-            "  protected abstract TestModule testModule();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf(TestModule module);",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf leaf(TestModule module) {",
-            "      Preconditions.checkNotNull(module);",
-            "      return new LeafImpl(module);",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private final TestModule testModule;",
-            "",
-            "      private LeafImpl(TestModule module) {",
-            "        this.testModule = module;",
-            "      }",
-            "",
-            "      @Override",
-            "      protected TestModule testModule() {",
-            "        return testModule;",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void generatedInstanceBinding() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Leaf build();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf.Builder leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  @Override",
-            "  public abstract Leaf.Builder leaf();",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf.Builder leaf() {",
-            "      return new LeafBuilder();",
-            "    }",
-            "",
-            "    private final class LeafBuilder implements Leaf.Builder {",
-            "      @Override",
-            "      public Leaf build() {",
-            "        return new LeafImpl();",
-            "      }",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private LeafImpl() {}",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void prunedGeneratedInstanceBinding() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PrunedSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface PrunedSubcomponent {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    PrunedSubcomponent build();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.InstallsPrunedSubcomponentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module(subcomponents = PrunedSubcomponent.class)",
-            "interface InstallsPrunedSubcomponentModule {}"),
-        JavaFileObjects.forSourceLines(
-            "test.DependsOnPrunedSubcomponentBuilder",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class DependsOnPrunedSubcomponentBuilder {",
-            "  @Inject DependsOnPrunedSubcomponentBuilder(PrunedSubcomponent.Builder builder) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.MaybeLeaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = InstallsPrunedSubcomponentModule.class)",
-            "interface MaybeLeaf {",
-            "  DependsOnPrunedSubcomponentBuilder dependsOnPrunedSubcomponentBuilder();",
-            "}"));
-    JavaFileObject generatedMaybeLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerMaybeLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerMaybeLeaf implements MaybeLeaf {",
-            "  protected DaggerMaybeLeaf() {}",
-            "",
-            "  @Override",
-            "  public DependsOnPrunedSubcomponentBuilder dependsOnPrunedSubcomponentBuilder() {",
-            "    return new DependsOnPrunedSubcomponentBuilder(",
-            "        (PrunedSubcomponent.Builder) getPrunedSubcomponentBuilder());",
-            "  }",
-            "",
-            "  protected abstract Object getPrunedSubcomponentBuilder();",
-            "",
-            "  protected abstract class PrunedSubcomponentImpl extends DaggerPrunedSubcomponent {",
-            "    protected PrunedSubcomponentImpl() {}",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerMaybeLeaf")
-        .hasSourceEquivalentTo(generatedMaybeLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PrunesGeneratedInstanceModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface PrunesGeneratedInstanceModule {",
-            "  @Provides",
-            "  static DependsOnPrunedSubcomponentBuilder pruneGeneratedInstance() {",
-            "    return new DependsOnPrunedSubcomponentBuilder(null);",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = PrunesGeneratedInstanceModule.class)",
-            "interface Root {",
-            "  MaybeLeaf actuallyLeaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public MaybeLeaf actuallyLeaf() {",
-            "    return new MaybeLeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class MaybeLeafImpl extends DaggerMaybeLeaf {",
-            "    private MaybeLeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected Object getPrunedSubcomponentBuilder() {",
-            "      " + PRUNED_METHOD_BODY,
-            "    }",
-            "",
-            "    @Override",
-            "    public DependsOnPrunedSubcomponentBuilder dependsOnPrunedSubcomponentBuilder() {",
-            "      return PrunesGeneratedInstanceModule_PruneGeneratedInstanceFactory",
-            "          .pruneGeneratedInstance();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void optionalBindings_boundAndSatisfiedInSameSubcomponent() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "SatisfiedInSub");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent(modules = {SubModule.class, BindsSatisfiedInSubModule.class})",
-            "interface Sub {",
-            "  Optional<SatisfiedInSub> satisfiedInSub();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.SubModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class SubModule {",
-            "  @BindsOptionalOf abstract SatisfiedInSub optionalSatisfiedInSub();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.BindsSatisfiedInSubModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class BindsSatisfiedInSubModule {",
-            "  @Provides static SatisfiedInSub provideSatisfiedInSub() {",
-            "      return new SatisfiedInSub();",
-            "  }",
-            "}"));
-    JavaFileObject generatedSubcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerSub",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerSub implements Sub {",
-            "  protected DaggerSub() {}",
-            "",
-            "  @Override",
-            "  public Optional<SatisfiedInSub> satisfiedInSub() {",
-            "    return Optional.of(",
-            "        BindsSatisfiedInSubModule_ProvideSatisfiedInSubFactory",
-            "            .provideSatisfiedInSub());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSub")
-        .hasSourceEquivalentTo(generatedSubcomponent);
-  }
-
-  @Test
-  public void optionalBindings_satisfiedInAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "SatisfiedInAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Optional<SatisfiedInAncestor> satisfiedInAncestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class LeafModule {",
-            "  @BindsOptionalOf abstract SatisfiedInAncestor optionalSatisfiedInAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Optional<SatisfiedInAncestor> satisfiedInAncestor() {",
-            "    return Optional.<SatisfiedInAncestor>empty();",
-            "  }",
-            "}");
-    Compilation compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class AncestorModule {",
-            "  @Provides",
-            "  static SatisfiedInAncestor satisfiedInAncestor(){",
-            "    return new SatisfiedInAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public final Optional<SatisfiedInAncestor> satisfiedInAncestor() {",
-            "      return Optional.of(AncestorModule_SatisfiedInAncestorFactory",
-            "          .satisfiedInAncestor());",
-            "    }",
-            "",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void optionalBindings_satisfiedInGrandAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "SatisfiedInGrandAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Optional<SatisfiedInGrandAncestor> satisfiedInGrandAncestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class LeafModule {",
-            "  @BindsOptionalOf",
-            "  abstract SatisfiedInGrandAncestor optionalSatisfiedInGrandAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Optional<SatisfiedInGrandAncestor> satisfiedInGrandAncestor() {",
-            "    return Optional.<SatisfiedInGrandAncestor>empty();",
-            "  }",
-            "}");
-    Compilation compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.GreatAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GreatAncestorModule.class)",
-            "interface GreatAncestor {",
-            "  Ancestor ancestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GreatAncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class GreatAncestorModule {",
-            "  @Provides",
-            "  static SatisfiedInGrandAncestor satisfiedInGrandAncestor(){",
-            "    return new SatisfiedInGrandAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedGreatAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerGreatAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGreatAncestor implements GreatAncestor {",
-            "  protected DaggerGreatAncestor() {}",
-            "",
-            "  protected abstract class AncestorImpl extends DaggerAncestor {",
-            "    protected AncestorImpl() {}",
-            "",
-            "    protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      protected LeafImpl() {}",
-            "",
-            "      @Override",
-            "      public final Optional<SatisfiedInGrandAncestor> satisfiedInGrandAncestor() {",
-            "        return Optional.of(",
-            "            GreatAncestorModule_SatisfiedInGrandAncestorFactory",
-            "                .satisfiedInGrandAncestor());",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGreatAncestor")
-        .hasSourceEquivalentTo(generatedGreatAncestor);
-  }
-
-  @Test
-  public void optionalBindings_nonComponentMethodDependencySatisfiedInAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(
-        filesToCompile, "SatisfiedInAncestor", "RequiresOptionalSatisfiedInAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  RequiresOptionalSatisfiedInAncestor requiresOptionalSatisfiedInAncestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.Optional;",
-            "",
-            "@Module",
-            "abstract class LeafModule {",
-            "  @Provides static RequiresOptionalSatisfiedInAncestor",
-            "      provideRequiresOptionalSatisfiedInAncestor(",
-            "          Optional<SatisfiedInAncestor> satisfiedInAncestor) {",
-            "    return new RequiresOptionalSatisfiedInAncestor();",
-            "  }",
-            "",
-            "  @BindsOptionalOf abstract SatisfiedInAncestor optionalSatisfiedInAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public RequiresOptionalSatisfiedInAncestor",
-            "      requiresOptionalSatisfiedInAncestor() {",
-            "    return LeafModule_ProvideRequiresOptionalSatisfiedInAncestorFactory",
-            "        .provideRequiresOptionalSatisfiedInAncestor(",
-            "            getOptionalOfSatisfiedInAncestor());",
-            "  }",
-            "",
-            "  protected Optional getOptionalOfSatisfiedInAncestor() {",
-            "    return Optional.<SatisfiedInAncestor>empty();",
-            "  }",
-            "}");
-    Compilation compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class AncestorModule {",
-            "  @Provides",
-            "  static SatisfiedInAncestor satisfiedInAncestor(){",
-            "    return new SatisfiedInAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected final Optional getOptionalOfSatisfiedInAncestor() {",
-            "      return Optional.of(",
-            "          AncestorModule_SatisfiedInAncestorFactory.satisfiedInAncestor());",
-            "    }",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void optionalBindings_boundInAncestorAndSatisfiedInGrandAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "SatisfiedInGrandAncestor");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Optional<SatisfiedInGrandAncestor> boundInAncestorSatisfiedInGrandAncestor();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Optional<SatisfiedInGrandAncestor>",
-            "      boundInAncestorSatisfiedInGrandAncestor();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class AncestorModule {",
-            "  @BindsOptionalOf",
-            "  abstract SatisfiedInGrandAncestor optionalSatisfiedInGrandAncestor();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Optional<SatisfiedInGrandAncestor>",
-            "        boundInAncestorSatisfiedInGrandAncestor() {",
-            "      return Optional.<SatisfiedInGrandAncestor>empty();",
-            "    }",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GrandAncestorModule.class)",
-            "interface GrandAncestor {",
-            "  Ancestor ancestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class GrandAncestorModule {",
-            "  @Provides static SatisfiedInGrandAncestor provideSatisfiedInGrandAncestor() {",
-            "    return new SatisfiedInGrandAncestor();",
-            "  }",
-            "}"));
-    JavaFileObject generatedGrandAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerGrandAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Optional;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGrandAncestor implements GrandAncestor {",
-            "  protected DaggerGrandAncestor() {}",
-            "",
-            "  protected abstract class AncestorImpl extends DaggerAncestor {",
-            "    protected AncestorImpl() {}",
-            "",
-            "    protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      protected LeafImpl() {}",
-            "",
-            "      @Override",
-            "      public final Optional<SatisfiedInGrandAncestor>",
-            "          boundInAncestorSatisfiedInGrandAncestor() {",
-            "        return Optional.of(",
-            "            GrandAncestorModule_ProvideSatisfiedInGrandAncestorFactory",
-            "                .provideSatisfiedInGrandAncestor());",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation =
-        compile(
-            filesToCompile.build()
-            , CompilerMode.JAVA7
-            );
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGrandAncestor")
-        .hasSourceEquivalentTo(generatedGrandAncestor);
-  }
-
-  @Test
-  public void provisionOverInjection_providedInAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.ProvidedInAncestor",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class ProvidedInAncestor {",
-            "  @Inject",
-            "  ProvidedInAncestor(String string) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  ProvidedInAncestor injectedInLeaf();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public ProvidedInAncestor injectedInLeaf() {",
-            "    return new ProvidedInAncestor(getString());",
-            "  }",
-            "",
-            "  protected abstract String getString();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static ProvidedInAncestor provideProvidedInAncestor() {",
-            "    return new ProvidedInAncestor(\"static\");",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public final ProvidedInAncestor injectedInLeaf() {",
-            "      return AncestorModule_ProvideProvidedInAncestorFactory",
-            "          .provideProvidedInAncestor();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void provisionOverInjection_providedInGrandAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.ProvidedInGrandAncestor",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class ProvidedInGrandAncestor {",
-            "  @Inject",
-            "  ProvidedInGrandAncestor(String string) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  ProvidedInGrandAncestor injectedInLeaf();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public ProvidedInGrandAncestor injectedInLeaf() {",
-            "    return new ProvidedInGrandAncestor(getString());",
-            "  }",
-            "",
-            "  protected abstract String getString();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GrandAncestorModule.class)",
-            "interface GrandAncestor {",
-            "  Ancestor ancestor();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.GrandAncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class GrandAncestorModule {",
-            "  @Provides",
-            "  static ProvidedInGrandAncestor provideProvidedInGrandAncestor() {",
-            "    return new ProvidedInGrandAncestor(\"static\");",
-            "  }",
-            "}"));
-    JavaFileObject generatedGrandAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerGrandAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerGrandAncestor implements GrandAncestor {",
-            "  protected DaggerGrandAncestor() {}",
-            "",
-            "  protected abstract class AncestorImpl extends DaggerAncestor {",
-            "    protected AncestorImpl() {}",
-            "",
-            "    protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      protected LeafImpl() {}",
-            "",
-            "      @Override",
-            "      public final ProvidedInGrandAncestor injectedInLeaf() {",
-            "        return GrandAncestorModule_ProvideProvidedInGrandAncestorFactory",
-            "            .provideProvidedInGrandAncestor();",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerGrandAncestor")
-        .hasSourceEquivalentTo(generatedGrandAncestor);
-  }
-
-  @Test
-  public void provisionOverInjection_indirectDependency() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.ProvidedInAncestor",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class ProvidedInAncestor {",
-            "  @Inject",
-            "  ProvidedInAncestor(String string) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.InjectedInLeaf",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectedInLeaf {",
-            "  @Inject",
-            "  InjectedInLeaf(ProvidedInAncestor providedInAncestor) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  InjectedInLeaf injectedInLeaf();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public InjectedInLeaf injectedInLeaf() {",
-            "    return new InjectedInLeaf((ProvidedInAncestor) getProvidedInAncestor());",
-            "  }",
-            "",
-            "  protected abstract String getString();",
-            "",
-            "  protected Object getProvidedInAncestor() {",
-            "    return new ProvidedInAncestor(getString());",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static ProvidedInAncestor provideProvidedInAncestor() {",
-            "    return new ProvidedInAncestor(\"static\");",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected final Object getProvidedInAncestor() {",
-            "      return AncestorModule_ProvideProvidedInAncestorFactory",
-            "          .provideProvidedInAncestor();",
-            "    }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void provisionOverInjection_prunedIndirectDependency() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "PrunedDependency");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.InjectsPrunedDependency",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsPrunedDependency {",
-            "  @Inject",
-            "  InjectsPrunedDependency(PrunedDependency prunedDependency) {}",
-            "",
-            "  private InjectsPrunedDependency() { }",
-            "",
-            "  static InjectsPrunedDependency create() { return new InjectsPrunedDependency(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  InjectsPrunedDependency injectsPrunedDependency();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return new InjectsPrunedDependency((PrunedDependency) getPrunedDependency());",
-            "  }",
-            "",
-            "  protected abstract Object getPrunedDependency();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class RootModule {",
-            "  @Provides",
-            "  static InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return InjectsPrunedDependency.create();",
-            "  }",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf leaf() {",
-            "    return new LeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    @Deprecated",
-            "    public Builder rootModule(RootModule rootModule) {",
-            "      Preconditions.checkNotNull(rootModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected Object getPrunedDependency() {",
-            "      " + PRUNED_METHOD_BODY,
-            "    }",
-            "",
-            "    @Override",
-            "    public InjectsPrunedDependency injectsPrunedDependency() {",
-            "      return RootModule_InjectsPrunedDependencyFactory",
-            "          .injectsPrunedDependency();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void provisionOverInjection_prunedDirectDependency_prunedInConcreteImplementation() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        // The binding for PrunedDependency will always exist, but will change from
-        // ModifiableBindingType.INJECTION to ModifiableBindingType.MISSING. We should correctly
-        // ignore this change leave the modifiable binding method alone
-        JavaFileObjects.forSourceLines(
-            "test.PrunedDependency",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class PrunedDependency {",
-            "  @Inject PrunedDependency() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.InjectsPrunedDependency",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsPrunedDependency {",
-            "  @Inject",
-            "  InjectsPrunedDependency(PrunedDependency prunedDependency) {}",
-            "",
-            "  private InjectsPrunedDependency() { }",
-            "",
-            "  static InjectsPrunedDependency create() { return new InjectsPrunedDependency(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  InjectsPrunedDependency injectsPrunedDependency();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return new InjectsPrunedDependency((PrunedDependency) getPrunedDependency());",
-            "  }",
-            "",
-            "  protected Object getPrunedDependency() {",
-            "    return new PrunedDependency();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class RootModule {",
-            "  @Provides",
-            "  static InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return InjectsPrunedDependency.create();",
-            "  }",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf leaf() {",
-            "    return new LeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    @Deprecated",
-            "    public Builder rootModule(RootModule rootModule) {",
-            "      Preconditions.checkNotNull(rootModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public InjectsPrunedDependency injectsPrunedDependency() {",
-            "      return RootModule_InjectsPrunedDependencyFactory",
-            "          .injectsPrunedDependency();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void provisionOverInjection_prunedDirectDependency_prunedInAbstractImplementation() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        // The binding for PrunedDependency will always exist, but will change from
-        // ModifiableBindingType.INJECTION to ModifiableBindingType.MISSING. We should correctly
-        // ignore this change leave the modifiable binding method alone
-        JavaFileObjects.forSourceLines(
-            "test.PrunedDependency",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class PrunedDependency {",
-            "  @Inject PrunedDependency() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.InjectsPrunedDependency",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsPrunedDependency {",
-            "  @Inject",
-            "  InjectsPrunedDependency(PrunedDependency prunedDependency) {}",
-            "",
-            "  private InjectsPrunedDependency() { }",
-            "",
-            "  static InjectsPrunedDependency create() { return new InjectsPrunedDependency(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  InjectsPrunedDependency injectsPrunedDependency();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return new InjectsPrunedDependency((PrunedDependency) getPrunedDependency());",
-            "  }",
-            "",
-            "  protected Object getPrunedDependency() {",
-            "    return new PrunedDependency();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static InjectsPrunedDependency injectsPrunedDependency() {",
-            "    return InjectsPrunedDependency.create();",
-            "  }",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public final InjectsPrunedDependency injectsPrunedDependency() {",
-            "      return AncestorModule_InjectsPrunedDependencyFactory",
-            "          .injectsPrunedDependency();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf leaf() {",
-            "      return new LeafImpl();",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private LeafImpl() {}",
-            // even though DaggerAncestor.LeafImpl.getPrunedDependency() was
-            // ModifiableBindingType.MISSING, it doesn't need to be reimplemented because there was
-            // a base implementation
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void productionSubcomponentAndModifiableFrameworkInstance() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Response", "ResponseDependency");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionSubcomponent;",
-            "import java.util.Set;",
-            "",
-            "@ProductionSubcomponent(modules = ResponseProducerModule.class)",
-            "interface Leaf {",
-            "  ListenableFuture<Set<Response>> responses();",
-            "",
-            "  @ProductionSubcomponent.Builder",
-            "  interface Builder {",
-            "    Leaf build();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.ResponseProducerModule",
-            "package test;",
-            "",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "final class ResponseProducerModule {",
-            "  @Produces",
-            "  @IntoSet",
-            "  static Response response(ResponseDependency responseDependency) {",
-            "    return new Response();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.internal.CancellationListener;",
-            "import dagger.producers.internal.Producers;",
-            "import dagger.producers.internal.SetProducer;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.Set;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf, CancellationListener {",
-            "  private Producer<Set<Response>> responsesEntryPoint;",
-            "  private Producer<Response> responseProducer;",
-            "  private Producer<Set<Response>> setOfResponseProducer;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.responseProducer =",
-            "        ResponseProducerModule_ResponseFactory.create(",
-            "            getProductionImplementationExecutorProvider(),",
-            "            getProductionComponentMonitorProvider(),",
-            "            getResponseDependencyProducer());",
-            "    this.setOfResponseProducer =",
-            "        SetProducer.<Response>builder(1, 0)",
-            "            .addProducer(responseProducer).build();",
-            "    this.responsesEntryPoint =",
-            "        Producers.entryPointViewOf(getSetOfResponseProducer(), this);",
-            "  }",
-            "",
-            "  @Override",
-            "  public ListenableFuture<Set<Response>> responses() {",
-            "    return responsesEntryPoint.get();",
-            "  }",
-            "",
-            "  protected abstract Provider<Executor>",
-            "      getProductionImplementationExecutorProvider();",
-            "",
-            "  protected abstract Provider<ProductionComponentMonitor>",
-            "      getProductionComponentMonitorProvider();",
-            "",
-            "  protected abstract Producer getResponseDependencyProducer();",
-            "",
-            "  protected Producer getSetOfResponseProducer() {",
-            "    return setOfResponseProducer;",
-            "  }",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-            "    Producers.cancel(getSetOfResponseProducer(), mayInterruptIfRunning);",
-            "    Producers.cancel(responseProducer, mayInterruptIfRunning);",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.ExecutorModule",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.MoreExecutors;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.producers.Production;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@Module",
-            "final class ExecutorModule {",
-            "  @Provides",
-            "  @Production",
-            "  static Executor executor() {",
-            "    return MoreExecutors.directExecutor();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(",
-            "  modules = {",
-            "      ExecutorModule.class,",
-            "      ResponseDependencyProducerModule.class,",
-            "      RootMultibindingModule.class,",
-            "  })",
-            "interface Root {",
-            "  Leaf.Builder leaf();",
-            "",
-            "  @ProductionComponent.Builder",
-            "  interface Builder {",
-            "    Root build();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.ResponseDependencyProducerModule",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.Futures;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "final class ResponseDependencyProducerModule {",
-            "  @Produces",
-            "  static ListenableFuture<ResponseDependency> responseDependency() {",
-            "    return Futures.immediateFuture(new ResponseDependency());",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.RootMultibindingModule",
-            "package test;",
-            "",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "final class RootMultibindingModule {",
-            "  @Produces",
-            "  @IntoSet",
-            "  static Response response() {",
-            "    return new Response();",
-            "  }",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.DoubleCheck;",
-            "import dagger.internal.InstanceFactory;",
-            "import dagger.internal.SetFactory;",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.internal.CancellationListener;",
-            "import dagger.producers.internal.DelegateProducer;",
-            "import dagger.producers.internal.Producers;",
-            "import dagger.producers.internal.SetProducer;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.Set;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root, CancellationListener {",
-            "  private Provider<Executor> productionImplementationExecutorProvider;",
-            "  private Provider<Root> rootProvider;",
-            "  private Provider<ProductionComponentMonitor> monitorProvider;",
-            "  private Producer<ResponseDependency> responseDependencyProducer;",
-            "  private Producer<Response> responseProducer;",
-            "",
-            "  private DaggerRoot() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  public static Root.Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.productionImplementationExecutorProvider =",
-            "        DoubleCheck.provider((Provider) ExecutorModule_ExecutorFactory.create());",
-            "    this.rootProvider = InstanceFactory.create((Root) this);",
-            "    this.monitorProvider =",
-            "        DoubleCheck.provider(",
-            "            Root_MonitoringModule_MonitorFactory.create(",
-            "                rootProvider,",
-            "                SetFactory.<ProductionComponentMonitor.Factory>empty()));",
-            "    this.responseDependencyProducer =",
-            "        ResponseDependencyProducerModule_ResponseDependencyFactory.create(",
-            "            productionImplementationExecutorProvider, monitorProvider);",
-            "    this.responseProducer =",
-            "        RootMultibindingModule_ResponseFactory.create(",
-            "            productionImplementationExecutorProvider, monitorProvider);",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf.Builder leaf() {",
-            "    return new LeafBuilder();",
-            "  }",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-            "    Producers.cancel(responseProducer, mayInterruptIfRunning);",
-            "    Producers.cancel(responseDependencyProducer, mayInterruptIfRunning);",
-            "  }",
-            "",
-            "  private static final class Builder implements Root.Builder {",
-            "    @Override",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  private final class LeafBuilder implements Leaf.Builder {",
-            "    @Override",
-            "    public Leaf build() {",
-            "      return new LeafImpl();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf implements CancellationListener {",
-            "    private Producer<Set<Response>> setOfResponseProducer = new DelegateProducer<>();",
-            "",
-            "    private LeafImpl() {",
-            "      configureInitialization();",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      DelegateProducer.setDelegate(",
-            "          setOfResponseProducer,",
-            "          SetProducer.<Response>builder(1, 1)",
-            "              .addCollectionProducer(super.getSetOfResponseProducer())",
-            "              .addProducer(DaggerRoot.this.responseProducer)",
-            "              .build());",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Provider<Executor> getProductionImplementationExecutorProvider() {",
-            "      return DaggerRoot.this.productionImplementationExecutorProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Provider<ProductionComponentMonitor>",
-            "        getProductionComponentMonitorProvider() {",
-            "      return DaggerRoot.this.monitorProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Producer getResponseDependencyProducer() {",
-            "      return DaggerRoot.this.responseDependencyProducer;",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Producer getSetOfResponseProducer() {",
-            "      return setOfResponseProducer;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void lazyOfModifiableBinding() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Lazy;",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Lazy<MissingInLeaf> lazy();",
-            "  Provider<Lazy<MissingInLeaf>> providerOfLazy();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.Lazy;",
-            "import dagger.internal.DoubleCheck;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.ProviderOfLazy;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Lazy<MissingInLeaf> lazy() {",
-            "    return DoubleCheck.lazy(getMissingInLeafProvider());",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<Lazy<MissingInLeaf>> providerOfLazy() {",
-            "    return ProviderOfLazy.create(getMissingInLeafProvider());",
-            "  }",
-            "",
-            "  protected abstract Provider getMissingInLeafProvider();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class AncestorModule {",
-            "  @Provides",
-            "  static MissingInLeaf satisfiedInAncestor() { return new MissingInLeaf(); }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected final Provider getMissingInLeafProvider() {",
-            "      return AncestorModule_SatisfiedInAncestorFactory.create();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void missingBindingAccessInLeafAndAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(
-        filesToCompile, "Missing", "DependsOnMissing", "ProvidedInAncestor_InducesSetBinding");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Provides;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  static DependsOnMissing test(",
-            "      Missing missing,",
-            "      Provider<Missing> missingProvider,",
-            "      ProvidedInAncestor_InducesSetBinding missingInLeaf) {",
-            "    return new DependsOnMissing();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Object unresolvedSetBinding(",
-            "      Missing missing, Provider<Missing> missingProvider) {",
-            "    return new Object();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  DependsOnMissing instance();",
-            "  Provider<DependsOnMissing> frameworkInstance();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Provider<DependsOnMissing> testProvider;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.testProvider =",
-            "        LeafModule_TestFactory.create(",
-            "            getMissingProvider(), getProvidedInAncestor_InducesSetBindingProvider());",
-            "  }",
-            "",
-            "  @Override",
-            "  public DependsOnMissing instance() {",
-            "    return LeafModule_TestFactory.test(",
-            // TODO(b/117833324): remove these unnecessary casts
-            "        (Missing) getMissing(),",
-            "        getMissingProvider(),",
-            "        (ProvidedInAncestor_InducesSetBinding)",
-            "            getProvidedInAncestor_InducesSetBinding());",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<DependsOnMissing> frameworkInstance() {",
-            "    return testProvider;",
-            "  }",
-            "",
-            "  protected abstract Object getMissing();",
-            "  protected abstract Provider getMissingProvider();",
-            "  protected abstract Object getProvidedInAncestor_InducesSetBinding();",
-            "  protected abstract Provider getProvidedInAncestor_InducesSetBindingProvider();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Provides;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static ProvidedInAncestor_InducesSetBinding providedInAncestor(",
-            "      Set<Object> setThatInducesMissingBindingInChildSubclassImplementation) {",
-            "    return new ProvidedInAncestor_InducesSetBinding();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Object setContribution() {",
-            "    return new Object();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.SetFactory;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private Provider<Object> unresolvedSetBindingProvider;",
-            "    private Provider<Set<Object>> setOfObjectProvider;",
-            "    private Provider<ProvidedInAncestor_InducesSetBinding> ",
-            "        providedInAncestorProvider = ",
-            "            new DelegateFactory<>();",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected void configureInitialization() {",
-            "      super.configureInitialization();",
-            "      initialize();",
-            "    }",
-            "",
-            "    private Object getUnresolvedSetBinding() {",
-            "      return LeafModule_UnresolvedSetBindingFactory.unresolvedSetBinding(",
-            // TODO(b/117833324): remove this unnecessary cast
-            "          (Missing) getMissing(), getMissingProvider());",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      this.unresolvedSetBindingProvider =",
-            "          LeafModule_UnresolvedSetBindingFactory.create(getMissingProvider());",
-            "      this.setOfObjectProvider =",
-            "          SetFactory.<Object>builder(2, 0)",
-            "              .addProvider(AncestorModule_SetContributionFactory.create())",
-            "              .addProvider(unresolvedSetBindingProvider)",
-            "              .build();",
-            "      DelegateFactory.setDelegate(",
-            "          providedInAncestorProvider,",
-            "          AncestorModule_ProvidedInAncestorFactory.create(getSetOfObjectProvider()));",
-            "    }",
-            "",
-            "    protected Set<Object> getSetOfObject() {",
-            "      return ImmutableSet.<Object>of(",
-            "          AncestorModule_SetContributionFactory.setContribution(),",
-            "          getUnresolvedSetBinding());",
-            "    }",
-            "",
-            "    @Override",
-            "    protected final Object getProvidedInAncestor_InducesSetBinding() {",
-            "      return AncestorModule_ProvidedInAncestorFactory.providedInAncestor(",
-            "          getSetOfObject());",
-            "    }",
-            "",
-            "    protected Provider<Set<Object>> getSetOfObjectProvider() {",
-            "      return setOfObjectProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    protected final Provider getProvidedInAncestor_InducesSetBindingProvider() {",
-            "      return providedInAncestorProvider;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void subcomponentBuilders() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "InducesDependenciesOnBuilderFields");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  private final Object object;",
-            "",
-            "  LeafModule(Object object) {",
-            "    this.object = object;",
-            "  }",
-            "",
-            "  @Provides",
-            "  Object fromModule() {",
-            "    return object;",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.MultibindingsModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "interface MultibindingsModule {",
-            "  @Binds",
-            "  @IntoSet",
-            "  String string(String string);",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = {LeafModule.class, MultibindingsModule.class})",
-            "interface Leaf {",
-            "  int bindsInstance();",
-            "  Object fromModule();",
-            "  InducesDependenciesOnBuilderFields inducesDependenciesOnBuilderFields();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder bindsInstance(int boundInstance);",
-            "    @BindsInstance Builder inducedInSubclass(String induced);",
-            "    Builder module(LeafModule module);",
-            "",
-            "    Leaf build();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Integer bindsInstance;",
-            "  private LeafModule leafModule;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization(",
-            "      LeafModule leafModuleParam, Integer bindsInstanceParam) {",
-            "    this.bindsInstance = bindsInstanceParam;",
-            "    this.leafModule = leafModuleParam;",
-            "  }",
-            "",
-            "  @Override",
-            "  public int bindsInstance() {",
-            "    return bindsInstance;",
-            "  }",
-            "",
-            "  @Override",
-            "  public Object fromModule() {",
-            "    return LeafModule_FromModuleFactory.fromModule(leafModule());",
-            "  }",
-            "",
-            "  @Override",
-            "  public abstract InducesDependenciesOnBuilderFields",
-            "      inducesDependenciesOnBuilderFields();",
-            "",
-            "  protected LeafModule leafModule() {",
-            "    return leafModule;",
-            "  }",
-            "",
-            "  public abstract static class Builder implements Leaf.Builder {",
-            "    protected Integer bindsInstance;",
-            "    protected String inducedInSubclass;",
-            "    protected LeafModule leafModule;",
-            "",
-            "    @Override",
-            "    public Builder bindsInstance(int boundInstance) {",
-            "      this.bindsInstance = Preconditions.checkNotNull(boundInstance);",
-            "      return this;",
-            "    }",
-            "",
-            "    @Override",
-            "    public Builder inducedInSubclass(String induced) {",
-            "      this.inducedInSubclass = Preconditions.checkNotNull(induced);",
-            "      return this;",
-            "    }",
-            "",
-            "    @Override",
-            "    public Builder module(LeafModule module) {",
-            "      this.leafModule = Preconditions.checkNotNull(module);",
-            "      return this;",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = MultibindingInducingModule.class)",
-            "interface Ancestor {",
-            "  Leaf.Builder leaf();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.MultibindingInducingModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import dagger.Provides;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface MultibindingInducingModule {",
-            "  @Provides",
-            "  static InducesDependenciesOnBuilderFields induce(",
-            "      Set<String> multibindingWithBuilderFieldDeps) { ",
-            "    return new InducesDependenciesOnBuilderFields();",
-            "  }",
-            "",
-            "  @Multibinds",
-            "  Set<String> multibinding();",
-            "}"));
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  @Override",
-            "  public abstract Leaf.Builder leaf();",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    private String inducedInSubclass;",
-            "",
-            "    protected LeafImpl() {}",
-            "",
-            "    protected void configureInitialization(",
-            "        LeafModule leafModule,",
-            "        Integer bindsInstance,",
-            "        String inducedInSubclassParam) {",
-            "      this.inducedInSubclass = inducedInSubclassParam;",
-            "      configureInitialization(leafModule, bindsInstance);",
-            "    }",
-            "",
-            "    protected Set<String> getSetOfString() {",
-            "      return ImmutableSet.<String>of(inducedInSubclass);",
-            "    }",
-            "",
-            "    @Override",
-            "    public final InducesDependenciesOnBuilderFields",
-            "        inducesDependenciesOnBuilderFields() {",
-            "      return MultibindingInducingModule_InduceFactory.induce(getSetOfString());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Ancestor ancestor() {",
-            "    return new AncestorImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    private AncestorImpl() {}",
-            "",
-            "    @Override",
-            "    public Leaf.Builder leaf() {",
-            "      return new LeafBuilder();",
-            "    }",
-            "",
-            "    private final class LeafBuilder extends DaggerLeaf.Builder {",
-            "      @Override",
-            "      public Leaf build() {",
-            // TODO(b/117833324): Can we stick the validations into a method on the base class
-            // builder so that the contents of this method are just call to that and then new
-            // FooImpl? But repeated modules may make this more complicated, since those *should*
-            // be null
-            "        Preconditions.checkBuilderRequirement(bindsInstance, Integer.class);",
-            "        Preconditions.checkBuilderRequirement(inducedInSubclass, String.class);",
-            "        Preconditions.checkBuilderRequirement(leafModule, LeafModule.class);",
-            "        return new LeafImpl(leafModule, bindsInstance, inducedInSubclass);",
-            "      }",
-            "    }",
-            "",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      private final LeafModule leafModule;",
-            "",
-            "      private LeafImpl(",
-            "          LeafModule leafModuleParam,",
-            "          Integer bindsInstance,",
-            "          String inducedInSubclass) {",
-            "        this.leafModule = leafModuleParam;",
-            "        configureInitialization(leafModuleParam, bindsInstance, inducedInSubclass);",
-            "      }",
-            "",
-            "      @Override",
-            "      protected LeafModule leafModule() {",
-            "        return leafModule;",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void subcomponentBuilders_moduleWithUnusedInstanceBindings() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Used", "Unused");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithUsedBinding",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ModuleWithUsedBinding {",
-            "  @Provides",
-            "  Used used() {",
-            "    return new Used();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithUnusedBinding",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ModuleWithUnusedBinding {",
-            "  @Provides",
-            "  Unused unused() {",
-            "    return new Unused();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = {ModuleWithUsedBinding.class, ModuleWithUnusedBinding.class})",
-            "interface Leaf {",
-            "  Used used();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Builder setUsed(ModuleWithUsedBinding module);",
-            "    Builder setUnused(ModuleWithUnusedBinding module);",
-            "    Leaf build();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private ModuleWithUsedBinding moduleWithUsedBinding;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization(",
-            "      ModuleWithUsedBinding moduleWithUsedBindingParam) {",
-            "    this.moduleWithUsedBinding = moduleWithUsedBindingParam;",
-            "  }",
-            "",
-            "  @Override",
-            "  public Used used() {",
-            "    return ModuleWithUsedBinding_UsedFactory.used(",
-            "        moduleWithUsedBinding());",
-            "  }",
-            "",
-            "  protected ModuleWithUsedBinding moduleWithUsedBinding() {",
-            "    return moduleWithUsedBinding;",
-            "  }",
-            "",
-            "  public abstract static class Builder implements Leaf.Builder {",
-            "    protected ModuleWithUsedBinding moduleWithUsedBinding;",
-            "    protected ModuleWithUnusedBinding moduleWithUnusedBinding;",
-            "",
-            "    @Override",
-            "    public Builder setUsed(ModuleWithUsedBinding module) {",
-            "      this.moduleWithUsedBinding = Preconditions.checkNotNull(module);",
-            "      return this;",
-            "    }",
-            "",
-            "    @Override",
-            "    public Builder setUnused(ModuleWithUnusedBinding module) {",
-            "      this.moduleWithUnusedBinding = Preconditions.checkNotNull(module);",
-            "      return this;",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  Leaf.Builder leaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf.Builder leaf() {",
-            "    return new LeafBuilder();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  private final class LeafBuilder extends DaggerLeaf.Builder {",
-            "    @Override",
-            "    public Leaf build() {",
-            "      if (moduleWithUsedBinding == null) {",
-            "        this.moduleWithUsedBinding = new ModuleWithUsedBinding();",
-            "      }",
-            // ModuleWithUnusedBinding is not verified since it's not used
-            "      return new LeafImpl(moduleWithUsedBinding);",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private final ModuleWithUsedBinding moduleWithUsedBinding;",
-            "",
-            "    private LeafImpl(ModuleWithUsedBinding moduleWithUsedBindingParam) {",
-            "      this.moduleWithUsedBinding = moduleWithUsedBindingParam;",
-            "      configureInitialization(moduleWithUsedBindingParam);",
-            "    }",
-            "",
-            "    @Override",
-            "    protected ModuleWithUsedBinding moduleWithUsedBinding() {",
-            "      return moduleWithUsedBinding;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void subcomponentBuilders_repeatedModule() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RepeatedModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class RepeatedModule {",
-            "  @Provides",
-            "  int i() {",
-            "    return 1;",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = RepeatedModule.class)",
-            "interface Leaf {",
-            "  int i();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Builder repeatedModule(RepeatedModule repeatedModule);",
-            "    Leaf build();",
-            "  }",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private RepeatedModule repeatedModule;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization(RepeatedModule repeatedModuleParam) {",
-            "    this.repeatedModule = repeatedModuleParam;",
-            "  }",
-            "",
-            "  @Override",
-            "  public int i() {",
-            "    return repeatedModule().i();",
-            "  }",
-            "",
-            "  protected RepeatedModule repeatedModule() {",
-            "    return repeatedModule;",
-            "  }",
-            "",
-            "  public abstract static class Builder implements Leaf.Builder {",
-            "    protected RepeatedModule repeatedModule;",
-            "",
-            "    @Override",
-            "    public Builder repeatedModule(RepeatedModule repeatedModule) {",
-            "      this.repeatedModule = Preconditions.checkNotNull(repeatedModule);",
-            "      return this;",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RepeatedModule.class)",
-            "interface Root {",
-            "  Leaf.Builder leaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private final RepeatedModule repeatedModule;",
-            "",
-            "  private DaggerRoot(RepeatedModule repeatedModuleParam) {",
-            "    this.repeatedModule = repeatedModuleParam;",
-            "  }",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf.Builder leaf() {",
-            "    return new LeafBuilder();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private RepeatedModule repeatedModule;",
-            "",
-            "    private Builder() {}",
-            "",
-            "    public Builder repeatedModule(RepeatedModule repeatedModule) {",
-            "      this.repeatedModule = Preconditions.checkNotNull(repeatedModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Root build() {",
-            "      if (repeatedModule == null) {",
-            "        this.repeatedModule = new RepeatedModule();",
-            "      }",
-            "      return new DaggerRoot(repeatedModule);",
-            "    }",
-            "  }",
-            "",
-            "  private final class LeafBuilder extends DaggerLeaf.Builder {",
-            "    @Override",
-            "    public LeafBuilder repeatedModule(RepeatedModule repeatedModule) {",
-            "      throw new UnsupportedOperationException(",
-            "        String.format(",
-            "          \"%s cannot be set because it is inherited from the enclosing component\",",
-            "          RepeatedModule.class.getCanonicalName()));",
-            "    }",
-            "",
-            "    @Override",
-            "    public Leaf build() {",
-            "      return new LeafImpl();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {",
-            "      configureInitialization(null);",
-            "    }",
-            "",
-            "    @Override",
-            "    protected RepeatedModule repeatedModule() {",
-            "      return DaggerRoot.this.repeatedModule;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void bindsWithMissingDependency() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Binds;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Binds Object missingBindsDependency(MissingInLeaf missing);",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Object bindsWithMissingDependencyInLeaf();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Object bindsWithMissingDependencyInLeaf();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.MissingInLeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface MissingInLeafModule {",
-            "  @Provides",
-            "  static MissingInLeaf boundInRoot() {",
-            "    return new MissingInLeaf();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = MissingInLeafModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf leaf() {",
-            "    return new LeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public Object bindsWithMissingDependencyInLeaf() {",
-            "      return MissingInLeafModule_BoundInRootFactory.boundInRoot();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void bindsWithMissingDependency_pruned() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "MissingInLeaf");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Binds;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Binds Object missingBindsDependency(MissingInLeaf missing);",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.DependsOnBindsWithMissingDep",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class DependsOnBindsWithMissingDep {",
-            "  @Inject DependsOnBindsWithMissingDep(Object bindsWithMissingDep) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  DependsOnBindsWithMissingDep DependsOnBindsWithMissingDep();",
-            "}"));
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public DependsOnBindsWithMissingDep DependsOnBindsWithMissingDep() {",
-            "    return new DependsOnBindsWithMissingDep(getObject());",
-            "  }",
-            "",
-            "  protected abstract Object getObject();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PrunesInjectConstructorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface PrunesInjectConstructorModule {",
-            "  @Provides",
-            "  static DependsOnBindsWithMissingDep pruneInjectConstructor() {",
-            "    return new DependsOnBindsWithMissingDep(new Object());",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = PrunesInjectConstructorModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf leaf() {",
-            "    return new LeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {}",
-            "",
-            "    @Override",
-            "    protected Object getObject() {",
-            "      " + PRUNED_METHOD_BODY,
-            "    }",
-            "",
-            "    @Override",
-            "    public DependsOnBindsWithMissingDep DependsOnBindsWithMissingDep() {",
-            "      return PrunesInjectConstructorModule_PruneInjectConstructorFactory",
-            "          .pruneInjectConstructor();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void modifiedProducerFromProvider() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "DependsOnModifiedProducerFromProvider");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.Provides;",
-            "import java.util.Set;",
-            "",
-            "@ProducerModule",
-            "interface LeafModule {",
-            "  @Produces",
-            "  static DependsOnModifiedProducerFromProvider dependsOnModified(Set<String> set) {",
-            "    return new DependsOnModifiedProducerFromProvider();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.ProductionSubcomponent;",
-            "import java.util.Set;",
-            "",
-            "@ProductionSubcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Producer<DependsOnModifiedProducerFromProvider>",
-            "      dependsOnModifiedProducerFromProvider();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.internal.CancellationListener;",
-            "import dagger.producers.internal.Producers;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.Set;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf, CancellationListener {",
-            "  private Producer<DependsOnModifiedProducerFromProvider>",
-            "      dependsOnModifiedProducerFromProviderEntryPoint;",
-            "  private Producer<DependsOnModifiedProducerFromProvider> dependsOnModifiedProducer;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.dependsOnModifiedProducer =",
-            "        LeafModule_DependsOnModifiedFactory.create(",
-            "            getProductionImplementationExecutorProvider(),",
-            "            getProductionComponentMonitorProvider(),",
-            "            getSetOfStringProducer());",
-            "    this.dependsOnModifiedProducerFromProviderEntryPoint =",
-            "        Producers.entryPointViewOf(dependsOnModifiedProducer, this);",
-            "  }",
-            "",
-            "  @Override",
-            "  public Producer<DependsOnModifiedProducerFromProvider> ",
-            "      dependsOnModifiedProducerFromProvider() {",
-            "    return dependsOnModifiedProducerFromProviderEntryPoint;",
-            "  }",
-            "",
-            "  protected abstract Provider<Executor> ",
-            "      getProductionImplementationExecutorProvider();",
-            "",
-            "  protected abstract Provider<ProductionComponentMonitor>",
-            "      getProductionComponentMonitorProvider();",
-            "",
-            "  protected abstract Producer<Set<String>> getSetOfStringProducer();",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-            "    Producers.cancel(dependsOnModifiedProducer, mayInterruptIfRunning);",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.producers.Production;",
-            "import java.util.Set;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@Module",
-            "interface RootModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static String induceModificationInLeaf() {",
-            "    return new String();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @Production",
-            "  static Executor productionExecutor() {",
-            "    return null;",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.DoubleCheck;",
-            "import dagger.internal.InstanceFactory;",
-            "import dagger.internal.SetFactory;",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.internal.CancellationListener;",
-            "import dagger.producers.internal.DelegateProducer;",
-            "import dagger.producers.internal.Producers;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.Set;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private DaggerRoot() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Root create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Leaf leaf() {",
-            "    return new LeafImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public Root build() {",
-            "      return new DaggerRoot();",
-            "    }",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf implements CancellationListener {",
-            "    private Provider<Executor> productionImplementationExecutorProvider =",
-            "        new DelegateFactory<>();",
-            "    private Provider<Leaf> leafProvider;",
-            "    private Provider<ProductionComponentMonitor> monitorProvider =",
-            "        new DelegateFactory<>();",
-            "    private Provider<Set<String>> setOfStringProvider;",
-            "    private Producer<Set<String>> setOfStringProducer = new DelegateProducer<>();",
-            "",
-            "    private LeafImpl() {",
-            "      configureInitialization();",
-            "      initialize();",
-            "    }",
-            "",
-            "    @SuppressWarnings(\"unchecked\")",
-            "    private void initialize() {",
-            "      DelegateFactory.setDelegate(",
-            "          productionImplementationExecutorProvider,",
-            "          DoubleCheck.provider(",
-            "              (Provider) RootModule_ProductionExecutorFactory.create()));",
-            "      this.leafProvider = InstanceFactory.create((Leaf) this);",
-            "      DelegateFactory.setDelegate(",
-            "          monitorProvider,",
-            "          DoubleCheck.provider(",
-            "              Leaf_MonitoringModule_MonitorFactory.create(",
-            "                  leafProvider,",
-            "                  getSetOfProductionComponentMonitorFactoryProvider())));",
-            "      this.setOfStringProvider =",
-            "          SetFactory.<String>builder(1, 0)",
-            "              .addProvider(RootModule_InduceModificationInLeafFactory.create())",
-            "              .build();",
-            "      DelegateProducer.setDelegate(",
-            "          setOfStringProducer,",
-            "          Producers.producerFromProvider(getSetOfStringProvider()));",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Provider<Executor> getProductionImplementationExecutorProvider() {",
-            "      return productionImplementationExecutorProvider;",
-            "    }",
-            "",
-            "    protected Provider<Set<ProductionComponentMonitor.Factory>> ",
-            "        getSetOfProductionComponentMonitorFactoryProvider() {",
-            "      return SetFactory.<ProductionComponentMonitor.Factory>empty();",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Provider<ProductionComponentMonitor> ",
-            "        getProductionComponentMonitorProvider() {",
-            "      return monitorProvider;",
-            "    }",
-            "",
-            "    protected Provider<Set<String>> getSetOfStringProvider() {",
-            "      return setOfStringProvider;",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Producer<Set<String>> getSetOfStringProducer() {",
-            "      return setOfStringProducer;",
-            "    }",
-            "",
-            "    @Override",
-            "    public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-            "      super.onProducerFutureCancelled(mayInterruptIfRunning);",
-            "      Producers.cancel(getSetOfStringProducer(), mayInterruptIfRunning);",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .hasSourceEquivalentTo(generatedRoot);
-  }
-
-  @Test
-  public void modifiableBindingMethods_namesDedupedAcrossImplementations() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "foo.Thing",
-            "package foo;",
-            "", // force multi-line format
-            "public interface Thing extends CharSequence {}"),
-        JavaFileObjects.forSourceLines(
-            "bar.Thing",
-            "package bar;",
-            "", // force multi-line format
-            "public interface Thing extends Runnable {}"),
-        JavaFileObjects.forSourceLines(
-            "test.WillInduceSetOfRunnable",
-            "package test;",
-            "", // force multi-line format
-            "class WillInduceSetOfRunnable {}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Provides",
-            "  static CharSequence depOnFooThing(foo.Thing thing) {",
-            "    return thing.toString();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Runnable depOnBarThing(bar.Thing thing) {",
-            "    return () -> {};",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  CharSequence inducesFoo();",
-            "  WillInduceSetOfRunnable willInduceSetOfRunnable();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            "import foo.Thing;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public CharSequence inducesFoo() {",
-            "    return LeafModule_DepOnFooThingFactory.depOnFooThing(getThing());",
-            "  }",
-            "",
-            "  @Override",
-            "  public abstract WillInduceSetOfRunnable willInduceSetOfRunnable();",
-            "",
-            "  protected abstract Thing getThing();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static WillInduceSetOfRunnable induce(Set<Runnable> set) {",
-            "    return null;",
-            "  }",
-            "",
-            "  @Multibinds Set<Runnable> runnables();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import bar.Thing;",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class LeafImpl extends DaggerLeaf {",
-            "    protected LeafImpl() {}",
-            "",
-            "    private Runnable getDepOnBarThing() {",
-            "      return LeafModule_DepOnBarThingFactory.depOnBarThing(getThing2());",
-            "    }",
-            "",
-            "    protected abstract Thing getThing2();",
-            "",
-            "    protected Set<Runnable> getSetOfRunnable() {",
-            "      return ImmutableSet.<Runnable>of(getDepOnBarThing());",
-            "    }",
-            "",
-            "    @Override",
-            "    public final WillInduceSetOfRunnable willInduceSetOfRunnable() {",
-            "      return AncestorModule_InduceFactory.induce(getSetOfRunnable());",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  /**
-   * This test verifies that Dagger can find the appropriate child subcomponent
-   * super-implementation, even if it is not enclosed in the current component's
-   * super-implementation. This can happen if a subcomponent is installed with a module's {@code
-   * subcomponents} attribute, but the binding is not accessed in a super-implementation. To exhibit
-   * this, we use multibindings that reference the pruned subcomponent, but make the multibinding
-   * also unresolved in the base implementation. An ancestor component defines a binding that
-   * depends on the multibinding, which induces the previously unresolved multibinding
-   * contributions, which itself induces the previously unresolved subcomponent.
-   */
-  @Test
-  public void subcomponentInducedFromAncestor() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Inducer");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.InducedSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface InducedSubcomponent {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    InducedSubcomponent build();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.MaybeLeaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = InducedSubcomponentModule.class)",
-            "interface MaybeLeaf {",
-            "  Inducer inducer();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.MaybeLeaf",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module(subcomponents = InducedSubcomponent.class)",
-            "interface InducedSubcomponentModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  static Object inducedSet(InducedSubcomponent.Builder builder) {",
-            "    return new Object();",
-            "  }",
-            "}"));
-
-    JavaFileObject generatedMaybeLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerMaybeLeaf implements MaybeLeaf {",
-            "  protected DaggerMaybeLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract Inducer inducer();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerMaybeLeaf")
-        .hasSourceEquivalentTo(generatedMaybeLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static Inducer inducer(Set<Object> set) {",
-            "    return null;",
-            "  }",
-            "",
-            "  @Multibinds Set<Object> set();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = AncestorModule.class)",
-            "interface Ancestor {",
-            "  MaybeLeaf noLongerLeaf();",
-            "}"));
-
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import dagger.internal.GenerationOptions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected DaggerAncestor() {}",
-            "",
-            "  protected abstract class MaybeLeafImpl extends DaggerMaybeLeaf {",
-            "    protected MaybeLeafImpl() {}",
-            "",
-            "    private Object getInducedSet() {",
-            "      return InducedSubcomponentModule_InducedSetFactory.inducedSet(",
-            // TODO(b/117833324): remove this unnecessary cast
-            "          (InducedSubcomponent.Builder) getInducedSubcomponentBuilder());",
-            "    }",
-            "",
-            "    protected abstract Object getInducedSubcomponentBuilder();",
-            "",
-            "    protected Set<Object> getSetOfObject() {",
-            "      return ImmutableSet.<Object>of(getInducedSet());",
-            "    }",
-            "",
-            "    @Override",
-            "    public final Inducer inducer() {",
-            "      return AncestorModule_InducerFactory.inducer(getSetOfObject());",
-            "    }",
-            "",
-            "    protected abstract class InducedSubcomponentImpl extends",
-            "        DaggerInducedSubcomponent {",
-            //       ^ Note that this is DaggerInducedSubcomponent, not
-            //         DaggerMaybeLeaf.InducedSubcomponentImpl
-            "      protected InducedSubcomponentImpl() {}",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .hasSourceEquivalentTo(generatedAncestor);
-  }
-
-  @Test
-  public void rootScopedAtInjectConstructor_effectivelyMissingInSubcomponent() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "ProvidesMethodRootScoped");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "public @interface RootScope {}"),
-        JavaFileObjects.forSourceLines(
-            "test.AtInjectRootScoped",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "@RootScope",
-            "class AtInjectRootScoped {",
-            "  @Inject AtInjectRootScoped() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  AtInjectRootScoped shouldBeEffectivelyMissingInLeaf();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public abstract AtInjectRootScoped shouldBeEffectivelyMissingInLeaf();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@RootScope",
-            "@Component",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    @Override",
-            "    public AtInjectRootScoped shouldBeEffectivelyMissingInLeaf() {",
-            "      return DaggerRoot.this.atInjectRootScopedProvider.get();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  @Test
-  public void prunedModuleWithInstanceState() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Pruned");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Modified",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Modified {",
-            "  @Inject Modified(Pruned pruned) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class LeafModule {",
-            "  @Provides",
-            "  Pruned pruned() {",
-            "    return new Pruned();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Modified modified();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  @Override",
-            "  public Modified modified() {",
-            "    return new Modified(LeafModule_PrunedFactory.pruned(leafModule()));",
-            "  }",
-            "",
-            "  protected abstract LeafModule leafModule();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class RootModule {",
-            "  @Provides",
-            "  static Modified modified() {",
-            "    return new Modified(null);",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    @Override",
-            "    public Modified modified() {",
-            "      return RootModule_ModifiedFactory.modified();",
-            "    }",
-            "",
-            "    @Override",
-            "    protected LeafModule leafModule() {",
-            "      return null;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  @Test
-  public void modifiableCycles() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class A {",
-            "  @Inject A(B b) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "class B {",
-            "  @Inject B(Provider<A> a) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Provider<A> frameworkInstanceCycle();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import dagger.internal.DelegateFactory;",
-            "import dagger.internal.GenerationOptions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Provider<A> aProvider;",
-            "  private Provider<B> bProvider;",
-            "",
-            "  protected DaggerLeaf() {}",
-            "",
-            "  protected void configureInitialization() {",
-            "    initialize();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.aProvider = new DelegateFactory<>();",
-            "    this.bProvider = B_Factory.create(frameworkInstanceCycle());",
-            "    DelegateFactory.setDelegate(aProvider, A_Factory.create(getBProvider()));",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<A> frameworkInstanceCycle() {",
-            "    return aProvider;",
-            "  }",
-            "",
-            "  protected Provider getBProvider() {",
-            "    return bProvider;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .hasSourceEquivalentTo(generatedLeaf);
-  }
-
-  /**
-   * This tests a regression case where the component builder in the base implementation used one
-   * set of disambiguated names from all of the {@link ComponentDescriptor#requirements()}, and the
-   * final implementation used a different set of disambiguated names from the resolved {@link
-   * BindingGraph#componentRequirements()}. This resulted in generated output that didn't compile,
-   * as the builder implementation attempted to use the new names in validation, which didn't line
-   * up with the old names.
-   */
-  @Test
-  public void componentBuilderFields_consistencyAcrossImplementations() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "a.Mod",
-            "package a;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Named;",
-            "",
-            "@Module",
-            "public class Mod {",
-            "  @Provides",
-            "  @Named(\"a\")",
-            "  int i() { return 0; }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "b.Mod",
-            "package b;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Named;",
-            "",
-            "@Module",
-            "public class Mod {",
-            "  @Provides",
-            "  @Named(\"b\")",
-            "  int i() { return 0; }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "c.Mod",
-            "package c;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Named;",
-            "",
-            "@Module",
-            "public class Mod {",
-            "  @Provides",
-            "  @Named(\"c\")",
-            "  int i() { return 0; }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.HasUnusedModuleLeaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Named;",
-            "",
-            "@Subcomponent(modules = {a.Mod.class, b.Mod.class, c.Mod.class})",
-            "interface HasUnusedModuleLeaf {",
-            "  @Named(\"a\") int a();",
-            // b omitted intentionally
-            "  @Named(\"c\") int c();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Builder setAMod(a.Mod mod);",
-            "    Builder setBMod(b.Mod mod);",
-            "    Builder setCMod(c.Mod mod);",
-            "    HasUnusedModuleLeaf build();",
-            "  }",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import a.Mod;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerHasUnusedModuleLeaf implements HasUnusedModuleLeaf {",
-            "  public abstract static class Builder implements HasUnusedModuleLeaf.Builder {",
-            "    protected Mod mod;",
-            "    protected b.Mod mod2;",
-            "    protected c.Mod mod3;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerHasUnusedModuleLeaf")
-        .containsElementsIn(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Root {",
-            "  HasUnusedModuleLeaf.Builder leaf();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            "import a.Mod;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  private final class HasUnusedModuleLeafBuilder",
-            "      extends DaggerHasUnusedModuleLeaf.Builder {",
-            "    @Override",
-            "    public HasUnusedModuleLeaf build() {",
-            "      if (mod == null) {",
-            "        this.mod = new Mod();",
-            "      }",
-            // Before this regression was fixed, `mod3` was instead `mod2`, since the `b.Mod` was
-            // pruned from the graph and did not need validation.
-            "      if (mod3 == null) {",
-            "        this.mod3 = new c.Mod();",
-            "      }",
-            "      return new HasUnusedModuleLeafImpl(mod, mod3);",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  @Test
-  public void dependencyExpressionCasting() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PublicType",
-            "package test;",
-            "", //
-            "public class PublicType {}"),
-        JavaFileObjects.forSourceLines(
-            "test.ModifiableNonPublicSubclass",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class ModifiableNonPublicSubclass extends PublicType {",
-            "  @Inject ModifiableNonPublicSubclass() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Parameterized",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Parameterized<T extends PublicType> {",
-            "  @Inject Parameterized(T t) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  Parameterized<ModifiableNonPublicSubclass> parameterizedWithNonPublicSubtype();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  @Override",
-            "  public Parameterized<ModifiableNonPublicSubclass> ",
-            "      parameterizedWithNonPublicSubtype() {",
-            "    return Parameterized_Factory.newInstance(",
-            "        (ModifiableNonPublicSubclass) getModifiableNonPublicSubclass());",
-            "  }",
-            "",
-            "  protected Object getModifiableNonPublicSubclass() {",
-            "    return new ModifiableNonPublicSubclass();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-  }
-
-  @Test
-  public void multipleComponentMethodsForSameBindingRequest() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  String string1();",
-            "  String string2();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  @Override",
-            "  public final String string2() {",
-            "    return string1();",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface RootModule {",
-            "  @Provides",
-            "  static String string() {",
-            "    return new String();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  protected final class LeafImpl extends DaggerLeaf {",
-            "    private LeafImpl() {}",
-            "",
-            "    @Override",
-            "    public String string1() {",
-            "      return RootModule_StringFactory.string();",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  @Test
-  public void boundInstanceUsedOnlyInInitialize() {
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  Provider<String> stringProvider();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    @BindsInstance",
-            "    Builder string(String string);",
-            "    Sub build();",
-            "  }",
-            "}");
-
-    JavaFileObject generated  =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.internal.InstanceFactory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerSub implements Sub {",
-            "  private Provider<String> stringProvider;",
-            "",
-            "  protected DaggerSub() {}",
-            "",
-            "  protected void configureInitialization(String stringParam) {",
-            "    initialize(stringParam);",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize(final String stringParam) {",
-            "    this.stringProvider = InstanceFactory.create(stringParam);",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<String> stringProvider() {",
-            "    return stringProvider;",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(ImmutableList.of(subcomponent));
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSub")
-        .containsElementsIn(generated);
-  }
-
-  @Test
-  public void packagePrivate_derivedFromFrameworkInstance_ComponentMethod() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PackagePrivate",
-            "package test;",
-            "",
-            "import dagger.Reusable;",
-            "import javax.inject.Inject;",
-            "",
-            "@Reusable", // Use @Reusable to force a framework field
-            "class PackagePrivate {",
-            "  @Inject PackagePrivate() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Leaf {",
-            "  PackagePrivate packagePrivate();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  private Provider<PackagePrivate> packagePrivateProvider;",
-            "",
-            "  @Override",
-            "  public PackagePrivate packagePrivate() {",
-            "    return (PackagePrivate) getPackagePrivateProvider().get();",
-            "  }",
-            "",
-            "  protected Provider getPackagePrivateProvider() {",
-            "    return packagePrivateProvider;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-  }
-
-  @Test
-  public void castModifiableMethodAccessedInFinalImplementation() {
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "PackagePrivate");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.PublicBaseType",
-            "package test;",
-            "", //
-            "public class PublicBaseType {}"),
-        JavaFileObjects.forSourceLines(
-            "test.PackagePrivateSubtype",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            // Force this to be a modifiable binding resolved in the ancestor even though the
-            // binding is requested in the leaf.
-            "@AncestorScope",
-            "class PackagePrivateSubtype extends PublicBaseType {",
-            "  @Inject PackagePrivateSubtype() {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope @interface AncestorScope {}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface LeafModule {",
-            "  @Binds PublicBaseType publicBaseType(PackagePrivateSubtype subtype);",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.InjectsOptionalOfModifiable",
-            "package test;",
-            "",
-            "import java.util.Optional;",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsOptionalOfModifiable {",
-            "  @Inject InjectsOptionalOfModifiable(",
-            "      Optional<PublicBaseType> optionalOfModifiable) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  InjectsOptionalOfModifiable injectsOptionalOfModifiable();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf {",
-            "  protected abstract Optional<PublicBaseType> getOptionalOfPublicBaseType();",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.InjectsPackagePrivateSubtype",
-            "package test;",
-            "",
-            "import java.util.Optional;",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsPackagePrivateSubtype {",
-            "  @Inject InjectsPackagePrivateSubtype(",
-            //     Force a modifiable binding method for PackagePrivateSubtype in Ancestor. The
-            //     final Leaf implementation will refer to this method, but will need to cast it
-            //     since the PackagePrivateSubtype is accessible from the current package, but the
-            //     method returns Object
-            "      PackagePrivateSubtype packagePrivateSubtype) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.AncestorModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface AncestorModule {",
-            "  @Provides",
-            "  static PackagePrivateSubtype packagePrivateSubtype() {",
-            "    return new PackagePrivateSubtype();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Ancestor",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@AncestorScope",
-            "@Subcomponent",
-            "interface Ancestor {",
-            "  InjectsPackagePrivateSubtype injectsPackagePrivateSubtype();",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedAncestor =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerAncestor",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerAncestor implements Ancestor {",
-            "  protected Object getPackagePrivateSubtype() {",
-            "    return getPackagePrivateSubtypeProvider().get();",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerAncestor")
-        .containsElementsIn(generatedAncestor);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface RootModule {",
-            "  @BindsOptionalOf",
-            "  PublicBaseType optionalPublicBaseType();",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = RootModule.class)",
-            "interface Root {",
-            "  Ancestor ancestor();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root {",
-            "  protected final class AncestorImpl extends DaggerAncestor {",
-            "    protected final class LeafImpl extends DaggerAncestor.LeafImpl {",
-            "      @Override",
-            "      protected Optional<PublicBaseType> getOptionalOfPublicBaseType() {",
-            "        return Optional.of(",
-            "            (PublicBaseType) AncestorImpl.this.getPackagePrivateSubtype());",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  @Test
-  public void injectInLeaf_ProductionInRoot() {
-    // most of this is also covered in ProducesMethodShadowsInjectConstructorTest, but this test
-    // asserts that the correct PrunedConcreteBindingExpression is used
-    ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder();
-    createSimplePackagePrivateClasses(filesToCompile, "Dependency", "Missing");
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.Injected",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Injected {",
-            "  @Inject Injected(Dependency dependency, Missing missing) {}",
-            "",
-            "  Injected(Dependency dependency) {}",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.LeafModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "interface LeafModule {",
-            "  @Produces",
-            "  static Object dependsOnInjectReplacedWithProduces(Injected injected) {",
-            "    return new Object();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Leaf",
-            "package test;",
-            "",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent(modules = LeafModule.class)",
-            "interface Leaf {",
-            "  Producer<Object> objectProducer();",
-            "}"));
-
-    JavaFileObject generatedLeaf =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerLeaf",
-            "package test;",
-            "",
-            GENERATION_OPTIONS_ANNOTATION,
-            GENERATED_ANNOTATION,
-            "public abstract class DaggerLeaf implements Leaf, CancellationListener {",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.injectedProvider = Injected_Factory.create(",
-            "        getDependencyProvider(), getMissingProvider());",
-            "    this.injectedProducer = Producers.producerFromProvider(getInjectedProvider());",
-            "    this.dependsOnInjectReplacedWithProducesProducer =",
-            "        LeafModule_DependsOnInjectReplacedWithProducesFactory.create(",
-            "            getProductionImplementationExecutorProvider(),",
-            "            getProductionComponentMonitorProvider(),",
-            "            getInjectedProducer());",
-            "    this.objectProducerEntryPoint =",
-            "        Producers.entryPointViewOf(",
-            "            dependsOnInjectReplacedWithProducesProducer, this);",
-            "  }",
-            "",
-            "  protected abstract Provider getDependencyProvider();",
-            "  protected abstract Provider getMissingProvider();",
-            "",
-            "  protected Provider getInjectedProvider() {",
-            "    return injectedProvider;",
-            "  }",
-            "",
-            "  protected Producer getInjectedProducer() {",
-            "    return injectedProducer;",
-            "  }",
-            "}");
-    Compilation compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerLeaf")
-        .containsElementsIn(generatedLeaf);
-
-    filesToCompile.add(
-        JavaFileObjects.forSourceLines(
-            "test.RootModule",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.MoreExecutors;",
-            "import dagger.Provides;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.Production;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@ProducerModule",
-            "interface RootModule {",
-            "  @Produces",
-            "  static Injected replaceInjectWithProduces(Dependency dependency) {",
-            "    return new Injected(dependency);",
-            "  }",
-            "",
-            "  @Produces",
-            "  static Dependency dependency() {",
-            "    return new Dependency();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @Production",
-            "  static Executor executor() {",
-            "    return MoreExecutors.directExecutor();",
-            "  }",
-            "}"),
-        JavaFileObjects.forSourceLines(
-            "test.Root",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(modules = RootModule.class)",
-            "interface Root {",
-            "  Leaf leaf();",
-            "}"));
-
-    JavaFileObject generatedRoot =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerRoot",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerRoot implements Root, CancellationListener {",
-            "  private Producer<Dependency> dependencyProducer;",
-            "  private Producer<Injected> replaceInjectWithProducesProducer;",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.productionImplementationExecutorProvider =",
-            "        DoubleCheck.provider((Provider) RootModule_ExecutorFactory.create());",
-            "    this.rootProvider = InstanceFactory.create((Root) this);",
-            "    this.monitorProvider =",
-            "        DoubleCheck.provider(",
-            "            Root_MonitoringModule_MonitorFactory.create(",
-            "                rootProvider,",
-            "                SetFactory.<ProductionComponentMonitor.Factory>empty()));",
-            "    this.dependencyProducer =",
-            "        RootModule_DependencyFactory.create(",
-            "            productionImplementationExecutorProvider, monitorProvider);",
-            "    this.replaceInjectWithProducesProducer =",
-            "        RootModule_ReplaceInjectWithProducesFactory.create(",
-            "            productionImplementationExecutorProvider,",
-            "            monitorProvider,",
-            "            dependencyProducer);",
-            "  }",
-            "",
-            "  protected final class LeafImpl extends DaggerLeaf",
-            "      implements CancellationListener {",
-            "    @Override",
-            "    protected Provider getDependencyProvider() {",
-            "      return MissingBindingFactory.create();",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Provider getMissingProvider() {",
-            "      return MissingBindingFactory.create();",
-            "    }",
-            "",
-            "    @Override",
-            "    protected Producer getInjectedProducer() {",
-            "      return DaggerRoot.this.replaceInjectWithProducesProducer;",
-            "    }",
-            "  }",
-            "}");
-    compilation = compile(filesToCompile.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRoot")
-        .containsElementsIn(generatedRoot);
-  }
-
-  // TODO(ronshapiro): remove copies from AheadOfTimeSubcomponents*Test classes
-  private void createSimplePackagePrivateClasses(
-      ImmutableList.Builder<JavaFileObject> filesBuilder, String... ancillaryClasses) {
-    for (String className : ancillaryClasses) {
-      filesBuilder.add(
-          JavaFileObjects.forSourceLines(
-              String.format("test.%s", className),
-              "package test;",
-              "",
-              String.format("class %s { }", className)));
-    }
-  }
-
-  private static Compilation compile(Iterable<JavaFileObject> files, CompilerMode... modes) {
-    return compilerWithOptions(
-            ObjectArrays.concat(
-                new CompilerMode[] {AHEAD_OF_TIME_SUBCOMPONENTS_MODE}, modes, CompilerMode.class))
-        .compile(files);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/AnnotationProtoConverterTest.java b/javatests/dagger/internal/codegen/AnnotationProtoConverterTest.java
deleted file mode 100644
index fda5859..0000000
--- a/javatests/dagger/internal/codegen/AnnotationProtoConverterTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2019 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.collect.Iterables.getOnlyElement;
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.auto.common.AnnotationMirrors;
-import com.google.testing.compile.CompilationRule;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import javax.lang.model.element.AnnotationMirror;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests {@link TypeProtoConverter}. */
-@RunWith(JUnit4.class)
-public class AnnotationProtoConverterTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-
-  private DaggerElements elements;
-  private DaggerTypes types;
-  private AnnotationProtoConverter annotationProtoConverter;
-
-  @Before
-  public void setUp() {
-    this.elements = new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
-    this.types = new DaggerTypes(compilationRule.getTypes(), elements);
-    this.annotationProtoConverter =
-        new AnnotationProtoConverter(new TypeProtoConverter(types, elements));
-  }
-
-  @Retention(RetentionPolicy.RUNTIME)
-  @interface TestAnnotation {
-    byte b();
-    boolean bool();
-    short s();
-    char c();
-    int i();
-    long l();
-    double d();
-    float f();
-
-    String string();
-    RetentionPolicy enumValue();
-    Class<?> classValue();
-    HasDefaults[] nestedAnnotations();
-  }
-
-  @Retention(RetentionPolicy.RUNTIME)
-  @interface HasDefaults {
-    int value() default 2;
-  }
-
-  @TestAnnotation(
-      b = 1,
-      bool = true,
-      s = 2,
-      c = 'c',
-      i = 4,
-      l = 5,
-      d = 6.0d,
-      f = 7.0f,
-      string = "hello, world",
-      enumValue = RetentionPolicy.CLASS,
-      classValue = AnnotationProtoConverter.class,
-      nestedAnnotations = {@HasDefaults, @HasDefaults(8)})
-  static class TestSubject {}
-
-  @Test
-  public void conversion() {
-    AnnotationMirror actual =
-        getOnlyElement(elements.getTypeElement(TestSubject.class).getAnnotationMirrors());
-    AnnotationMirror translated =
-        annotationProtoConverter.fromProto(AnnotationProtoConverter.toProto(actual));
-    assertThat(AnnotationMirrors.equivalence().equivalent(actual, translated)).isTrue();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/BUILD b/javatests/dagger/internal/codegen/BUILD
deleted file mode 100644
index ad214ff..0000000
--- a/javatests/dagger/internal/codegen/BUILD
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Tests for the Dagger compiler/codegen
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "compiler_tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen:base",
-        "//java/dagger/internal/codegen:binding",
-        "//java/dagger/internal/codegen:binding_graph_validation",
-        "//java/dagger/internal/codegen:processor",
-        "//java/dagger/internal/codegen:validation",
-        "//java/dagger/internal/codegen:writing",
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-        "//java/dagger/internal/codegen/serialization",
-        "//java/dagger/model",
-        "//java/dagger/model/testing",
-        "//java/dagger/producers",
-        "//java/dagger/spi",
-        "@com_google_auto_value_auto_value//jar",  # For AutoAnnotationProcessor
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/auto:value",
-        "@google_bazel_common//third_party/java/compile_testing",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/jsr250_annotations",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/mockito",
-        "@google_bazel_common//third_party/java/truth",
-        "@google_bazel_common//third_party/java/truth:truth8",
-    ],
-)
diff --git a/javatests/dagger/internal/codegen/BindingGraphCapturer.java b/javatests/dagger/internal/codegen/BindingGraphCapturer.java
deleted file mode 100644
index 503fd47..0000000
--- a/javatests/dagger/internal/codegen/BindingGraphCapturer.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.collect.ImmutableMap;
-import dagger.model.BindingGraph;
-import dagger.spi.BindingGraphPlugin;
-import dagger.spi.DiagnosticReporter;
-
-/**
- * A testing plugin that captures {@link dagger.model.BindingGraph}s for tests to make assertions
- * about.
- */
-// TODO(dpb): Move to dagger.spi.testing?
-final class BindingGraphCapturer implements BindingGraphPlugin {
-
-  private final ImmutableMap.Builder<String, BindingGraph> bindingGraphs = ImmutableMap.builder();
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    bindingGraphs.put(
-        bindingGraph
-            .rootComponentNode()
-            .componentPath()
-            .currentComponent()
-            .getQualifiedName()
-            .toString(),
-        bindingGraph);
-  }
-
-  /** Returns a map of binding graphs, indexed by the canonical name of the root component type. */
-  public ImmutableMap<String, BindingGraph> bindingGraphs() {
-    return bindingGraphs.build();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java b/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java
deleted file mode 100644
index 2496d8b..0000000
--- a/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java
+++ /dev/null
@@ -1,165 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class BindsInstanceValidationTest {
-  @Test
-  public void bindsInstanceInModule() {
-    JavaFileObject testModule =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @BindsInstance abstract void str(String string);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(testModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@BindsInstance methods should not be included in @Modules. Did you mean @Binds");
-  }
-
-  @Test
-  public void bindsInstanceInComponent() {
-    JavaFileObject testComponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  @BindsInstance String s(String s);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(testComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@BindsInstance methods should not be included in @Components. "
-                + "Did you mean to put it in a @Component.Builder?");
-  }
-
-  @Test
-  public void bindsInstanceNotAbstract() {
-    JavaFileObject notAbstract =
-        JavaFileObjects.forSourceLines(
-            "test.BindsInstanceNotAbstract",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "class BindsInstanceNotAbstract {",
-            "  @BindsInstance BindsInstanceNotAbstract bind(int unused) { return this; }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(notAbstract);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@BindsInstance methods must be abstract")
-        .inFile(notAbstract)
-        .onLine(7);
-  }
-
-  @Test
-  public void bindsInstanceNoParameters() {
-    JavaFileObject notAbstract =
-        JavaFileObjects.forSourceLines(
-            "test.BindsInstanceNoParameters",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "",
-            "interface BindsInstanceNoParameters {",
-            "  @BindsInstance void noParams();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(notAbstract);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@BindsInstance methods should have exactly one parameter for the bound type")
-        .inFile(notAbstract)
-        .onLine(6);
-  }
-
-  @Test
-  public void bindsInstanceManyParameters() {
-    JavaFileObject notAbstract =
-        JavaFileObjects.forSourceLines(
-            "test.BindsInstanceNoParameter",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "",
-            "interface BindsInstanceManyParameters {",
-            "  @BindsInstance void manyParams(int i, long l);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(notAbstract);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@BindsInstance methods should have exactly one parameter for the bound type")
-        .inFile(notAbstract)
-        .onLine(6);
-  }
-
-  @Test
-  public void bindsInstanceFrameworkType() {
-    JavaFileObject bindsFrameworkType =
-        JavaFileObjects.forSourceLines(
-            "test.BindsInstanceFrameworkType",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.producers.Producer;",
-            "import javax.inject.Provider;",
-            "",
-            "interface BindsInstanceFrameworkType {",
-            "  @BindsInstance void bindsProvider(Provider<Object> objectProvider);",
-            "  @BindsInstance void bindsProducer(Producer<Object> objectProducer);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(bindsFrameworkType);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@BindsInstance parameters must not be framework types")
-        .inFile(bindsFrameworkType)
-        .onLine(8);
-
-    assertThat(compilation)
-        .hadErrorContaining("@BindsInstance parameters must not be framework types")
-        .inFile(bindsFrameworkType)
-        .onLine(9);
-  }
-
-}
diff --git a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java b/javatests/dagger/internal/codegen/BindsMethodValidationTest.java
deleted file mode 100644
index 6ba9e3e..0000000
--- a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.collect.ImmutableList;
-import dagger.Module;
-import dagger.multibindings.IntKey;
-import dagger.multibindings.LongKey;
-import dagger.producers.ProducerModule;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Retention;
-import java.util.Collection;
-import javax.inject.Qualifier;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class BindsMethodValidationTest {
-  @Parameters
-  public static Collection<Object[]> data() {
-    return ImmutableList.copyOf(new Object[][] {{Module.class}, {ProducerModule.class}});
-  }
-
-  private final String moduleDeclaration;
-
-  public BindsMethodValidationTest(Class<? extends Annotation> moduleAnnotation) {
-    moduleDeclaration = "@" + moduleAnnotation.getCanonicalName() + " abstract class %s { %s }";
-  }
-
-  @Test
-  public void nonAbstract() {
-    assertThatMethod("@Binds Object concrete(String impl) { return null; }")
-        .hasError("must be abstract");
-  }
-
-  @Test
-  public void notAssignable() {
-    assertThatMethod("@Binds abstract String notAssignable(Object impl);").hasError("assignable");
-  }
-
-  @Test
-  public void moreThanOneParameter() {
-    assertThatMethod("@Binds abstract Object tooManyParameters(String s1, String s2);")
-        .hasError("one parameter");
-  }
-
-  @Test
-  public void typeParameters() {
-    assertThatMethod("@Binds abstract <S, T extends S> S generic(T t);")
-        .hasError("type parameters");
-  }
-
-  @Test
-  public void notInModule() {
-    assertThatMethodInUnannotatedClass("@Binds abstract Object bindObject(String s);")
-        .hasError("within a @Module or @ProducerModule");
-  }
-
-  @Test
-  public void throwsException() {
-    assertThatMethod("@Binds abstract Object throwsException(String s1) throws IOException;")
-        .importing(IOException.class)
-        .hasError("only throw unchecked");
-  }
-
-  @Test
-  public void returnsVoid() {
-    assertThatMethod("@Binds abstract void returnsVoid(Object impl);").hasError("void");
-  }
-
-  @Test
-  public void tooManyQualifiersOnMethod() {
-    assertThatMethod(
-            "@Binds @Qualifier1 @Qualifier2 abstract String tooManyQualifiers(String impl);")
-        .importing(Qualifier1.class, Qualifier2.class)
-        .hasError("more than one @Qualifier");
-  }
-
-  @Test
-  public void tooManyQualifiersOnParameter() {
-    assertThatMethod(
-            "@Binds abstract String tooManyQualifiers(@Qualifier1 @Qualifier2 String impl);")
-        .importing(Qualifier1.class, Qualifier2.class)
-        .hasError("more than one @Qualifier");
-  }
-
-  @Test
-  public void noParameters() {
-    assertThatMethod("@Binds abstract Object noParameters();").hasError("one parameter");
-  }
-
-  @Test
-  public void setElementsNotAssignable() {
-    assertThatMethod(
-            "@Binds @ElementsIntoSet abstract Set<String> bindSetOfIntegers(Set<Integer> ints);")
-        .hasError("assignable");
-  }
-
-  @Test
-  public void setElements_primitiveArgument() {
-    assertThatMethod("@Binds @ElementsIntoSet abstract Set<Number> bindInt(int integer);")
-        .hasError("assignable");
-  }
-
-  @Test
-  public void elementsIntoSet_withRawSets() {
-    assertThatMethod("@Binds @ElementsIntoSet abstract Set bindRawSet(HashSet hashSet);")
-        .hasError("cannot return a raw Set");
-  }
-
-  @Test
-  public void intoMap_noMapKey() {
-    assertThatMethod("@Binds @IntoMap abstract Object bindNoMapKey(String string);")
-        .hasError("methods of type map must declare a map key");
-  }
-
-  @Test
-  public void intoMap_multipleMapKeys() {
-    assertThatMethod(
-            "@Binds @IntoMap @IntKey(1) @LongKey(2L) abstract Object manyMapKeys(String string);")
-        .importing(IntKey.class, LongKey.class)
-        .hasError("may not have more than one map key");
-  }
-
-  private DaggerModuleMethodSubject assertThatMethod(String method) {
-    return assertThatModuleMethod(method).withDeclaration(moduleDeclaration);
-  }
-
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface Qualifier1 {}
-
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface Qualifier2 {}
-}
diff --git a/javatests/dagger/internal/codegen/BindsMissingDelegateValidationTest.java b/javatests/dagger/internal/codegen/BindsMissingDelegateValidationTest.java
deleted file mode 100644
index 28b75be..0000000
--- a/javatests/dagger/internal/codegen/BindsMissingDelegateValidationTest.java
+++ /dev/null
@@ -1,216 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests that errors are reported correctly when a {@code @Binds} method's delegate (the type of its
- * parameter) is missing.
- */
-@RunWith(JUnit4.class)
-public class BindsMissingDelegateValidationTest {
-  @Test
-  public void bindsMissingDelegate() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "",
-            "@Component(modules = C.TestModule.class)",
-            "interface C {",
-            "  Object object();",
-            "",
-            "  static class NotBound {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule {",
-            "    @Binds abstract Object bindObject(NotBound notBound);",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.C.NotBound cannot be provided")
-        .inFile(component)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void bindsMissingDelegate_duplicateBinding() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Component(modules = C.TestModule.class)",
-            "interface C {",
-            "  Object object();",
-            "",
-            "  static class NotBound {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule {",
-            "    @Binds abstract Object bindObject(NotBound notBound);",
-            "    @Provides static Object provideObject() { return new Object(); }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    // Some javacs report only the first error for each source line.
-    // Assert that one of the expected errors is reported.
-    assertThat(compilation)
-        .hadErrorContainingMatch(
-            "\\Qtest.C.NotBound cannot be provided\\E|"
-                + message(
-                    "\\Qjava.lang.Object is bound multiple times:",
-                    "    @Binds Object test.C.TestModule.bindObject(test.C.NotBound)",
-                    "    @Provides Object test.C.TestModule.provideObject()\\E"))
-        .inFile(component)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void bindsMissingDelegate_setBinding() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Component(modules = C.TestModule.class)",
-            "interface C {",
-            "  Set<Object> objects();",
-            "",
-            "  static class NotBound {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule {",
-            "    @Binds @IntoSet abstract Object bindObject(NotBound notBound);",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.C.NotBound cannot be provided")
-        .inFile(component)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void bindsMissingDelegate_mapBinding() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Component(modules = C.TestModule.class)",
-            "interface C {",
-            "  Map<String, Object> objects();",
-            "",
-            "  static class NotBound {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule {",
-            "    @Binds @IntoMap @StringKey(\"key\")",
-            "    abstract Object bindObject(NotBound notBound);",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.C.NotBound cannot be provided")
-        .inFile(component)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void bindsMissingDelegate_mapBinding_sameKey() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@Component(modules = C.TestModule.class)",
-            "interface C {",
-            "  Map<String, Object> objects();",
-            "",
-            "  static class NotBound {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule {",
-            "    @Binds @IntoMap @StringKey(\"key\")",
-            "    abstract Object bindObject(NotBound notBound);",
-            "",
-            "    @Provides @IntoMap @StringKey(\"key\")",
-            "    static Object provideObject() { return new Object(); }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    // Some javacs report only the first error for each source line.
-    assertThat(compilation)
-        .hadErrorContainingMatch(
-            "\\Qtest.C.NotBound cannot be provided\\E|"
-                + "\\Qsame map key is bound more than once\\E")
-        .inFile(component)
-        .onLineContaining("interface C");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/BindsOptionalOfMethodValidationTest.java b/javatests/dagger/internal/codegen/BindsOptionalOfMethodValidationTest.java
deleted file mode 100644
index fa44a6e..0000000
--- a/javatests/dagger/internal/codegen/BindsOptionalOfMethodValidationTest.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2016 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests {@link BindsOptionalOfMethodValidator}. */
-@RunWith(Parameterized.class)
-public class BindsOptionalOfMethodValidationTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> data() {
-    return ImmutableList.copyOf(new Object[][] {{Module.class}, {ProducerModule.class}});
-  }
-
-  private final String moduleDeclaration;
-
-  public BindsOptionalOfMethodValidationTest(Class<? extends Annotation> moduleAnnotation) {
-    moduleDeclaration = "@" + moduleAnnotation.getCanonicalName() + " abstract class %s { %s }";
-  }
-
-  @Test
-  public void nonAbstract() {
-    assertThatMethod("@BindsOptionalOf Object concrete() { return null; }")
-        .hasError("must be abstract");
-  }
-
-  @Test
-  public void hasParameters() {
-    assertThatMethod("@BindsOptionalOf abstract Object hasParameters(String s1);")
-        .hasError("parameters");
-  }
-
-  @Test
-  public void typeParameters() {
-    assertThatMethod("@BindsOptionalOf abstract <S> S generic();").hasError("type parameters");
-  }
-
-  @Test
-  public void notInModule() {
-    assertThatMethodInUnannotatedClass("@BindsOptionalOf abstract Object notInModule();")
-        .hasError("within a @Module or @ProducerModule");
-  }
-
-  @Test
-  public void throwsException() {
-    assertThatMethod("@BindsOptionalOf abstract Object throwsException() throws RuntimeException;")
-        .hasError("may not throw");
-  }
-
-  @Test
-  public void returnsVoid() {
-    assertThatMethod("@BindsOptionalOf abstract void returnsVoid();").hasError("void");
-  }
-
-  @Test
-  public void returnsMembersInjector() {
-    assertThatMethod("@BindsOptionalOf abstract MembersInjector<Object> returnsMembersInjector();")
-        .hasError("framework");
-  }
-
-  @Test
-  public void tooManyQualifiers() {
-    assertThatMethod(
-            "@BindsOptionalOf @Qualifier1 @Qualifier2 abstract String tooManyQualifiers();")
-        .importing(Qualifier1.class, Qualifier2.class)
-        .hasError("more than one @Qualifier");
-  }
-
-  @Test
-  public void intoSet() {
-    assertThatMethod("@BindsOptionalOf @IntoSet abstract String intoSet();")
-        .hasError("cannot have multibinding annotations");
-  }
-
-  @Test
-  public void elementsIntoSet() {
-    assertThatMethod("@BindsOptionalOf @ElementsIntoSet abstract Set<String> elementsIntoSet();")
-        .hasError("cannot have multibinding annotations");
-  }
-
-  @Test
-  public void intoMap() {
-    assertThatMethod("@BindsOptionalOf @IntoMap abstract String intoMap();")
-        .hasError("cannot have multibinding annotations");
-  }
-
-  /**
-   * Tests that @BindsOptionalOf @IntoMap actually causes module validation to fail.
-   *
-   * @see <a href="http://b/118434447">bug 118434447</a>
-   */
-  @Test
-  public void intoMapWithComponent() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @BindsOptionalOf @IntoMap Object object();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {}");
-
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cannot have multibinding annotations")
-        .inFile(module)
-        .onLineContaining("object();");
-  }
-
-  /** An injectable value object. */
-  public static final class Thing {
-    @Inject
-    Thing() {}
-  }
-
-  @Test
-  public void implicitlyProvidedType() {
-    assertThatMethod("@BindsOptionalOf abstract Thing thing();")
-        .importing(Thing.class)
-        .hasError("return unqualified types that have an @Inject-annotated constructor");
-  }
-
-  @Test
-  public void hasScope() {
-    assertThatMethod("@BindsOptionalOf @Singleton abstract String scoped();")
-        .importing(Singleton.class)
-        .hasError("cannot be scoped");
-  }
-
-  private DaggerModuleMethodSubject assertThatMethod(String method) {
-    return assertThatModuleMethod(method).withDeclaration(moduleDeclaration);
-  }
-
-  /** A qualifier. */
-  @Qualifier
-  public @interface Qualifier1 {}
-
-  /** A qualifier. */
-  @Qualifier
-  public @interface Qualifier2 {}
-}
diff --git a/javatests/dagger/internal/codegen/CompilerMode.java b/javatests/dagger/internal/codegen/CompilerMode.java
deleted file mode 100644
index 23aa312..0000000
--- a/javatests/dagger/internal/codegen/CompilerMode.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-
-/** The configuration options for compiler modes. */
-enum CompilerMode {
-  DEFAULT_MODE,
-  FAST_INIT_MODE("-Adagger.fastInit=enabled"),
-  AHEAD_OF_TIME_SUBCOMPONENTS_MODE(
-      "-Adagger.experimentalAheadOfTimeSubcomponents=enabled",
-      "-Adagger.emitModifiableMetadataAnnotations=disabled"),
-  JAVA7("-source", "7", "-target", "7"),
-  ;
-
-  /** Returns the compiler modes as a list of parameters for parameterized tests */
-  static final ImmutableList<Object[]> TEST_PARAMETERS =
-      ImmutableList.copyOf(
-          new Object[][] {{CompilerMode.DEFAULT_MODE}, {CompilerMode.FAST_INIT_MODE}});
-
-  private final ImmutableList<String> javacopts;
-
-  private CompilerMode(String... javacopts) {
-    this.javacopts = ImmutableList.copyOf(javacopts);
-  }
-
-  /** Returns the javacopts for this compiler mode. */
-  FluentIterable<String> javacopts() {
-    return FluentIterable.from(javacopts);
-  }
-
-  /**
-   * Returns a {@link JavaFileBuilder} that builds {@link javax.tools.JavaFileObject}s for this
-   * mode.
-   */
-  JavaFileBuilder javaFileBuilder(String qualifiedName) {
-    return new JavaFileBuilder(this, qualifiedName);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/Compilers.java b/javatests/dagger/internal/codegen/Compilers.java
deleted file mode 100644
index 3e08f63..0000000
--- a/javatests/dagger/internal/codegen/Compilers.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 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.StandardSystemProperty.JAVA_CLASS_PATH;
-import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;
-import static com.google.testing.compile.Compiler.javac;
-import static java.util.stream.Collectors.joining;
-
-import com.google.auto.value.processor.AutoAnnotationProcessor;
-import com.google.common.base.Splitter;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compiler;
-import javax.annotation.processing.Processor;
-
-/** {@link Compiler} instances for testing Dagger. */
-final class Compilers {
-  private static final String GUAVA = "guava";
-
-  static final ImmutableList<String> CLASS_PATH_WITHOUT_GUAVA_OPTION =
-      ImmutableList.of(
-          "-classpath",
-          Splitter.on(PATH_SEPARATOR.value()).splitToList(JAVA_CLASS_PATH.value()).stream()
-              .filter(jar -> !jar.contains(GUAVA))
-              .collect(joining(PATH_SEPARATOR.value())));
-
-  /**
-   * Returns a compiler that runs the Dagger and {@code @AutoAnnotation} processors, along with
-   * extras.
-   */
-  static Compiler daggerCompiler(Processor... extraProcessors) {
-    ImmutableList.Builder<Processor> processors = ImmutableList.builder();
-    processors.add(new ComponentProcessor(), new AutoAnnotationProcessor());
-    processors.add(extraProcessors);
-    return javac().withProcessors(processors.build());
-  }
-
-  static Compiler compilerWithOptions(CompilerMode... compilerModes) {
-    FluentIterable<String> options = FluentIterable.of();
-    for (CompilerMode compilerMode : compilerModes) {
-      options = options.append(compilerMode.javacopts());
-    }
-    return daggerCompiler().withOptions(options);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentBuilderTest.java b/javatests/dagger/internal/codegen/ComponentBuilderTest.java
deleted file mode 100644
index f280bdd..0000000
--- a/javatests/dagger/internal/codegen/ComponentBuilderTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.COMPONENT_BUILDER;
-import static dagger.internal.codegen.ErrorMessages.creatorMessagesFor;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for {@link dagger.Component.Builder} */
-@RunWith(Parameterized.class)
-public class ComponentBuilderTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ComponentBuilderTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  private static final ErrorMessages.ComponentCreatorMessages MSGS =
-      creatorMessagesFor(COMPONENT_BUILDER);
-
-  @Test
-  public void testUsesBuildAndSetterNames() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String string() { return null; }",
-            "}");
-
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  String string();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    Builder setTestModule(TestModule testModule);",
-            "    TestComponent create();",
-            "  }",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private static final class Builder implements TestComponent.Builder {",
-            "    private TestModule testModule;",
-            "",
-            "    @Override",
-            "    public Builder setTestModule(TestModule testModule) {",
-            "      this.testModule = Preconditions.checkNotNull(testModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    @Override",
-            "    public TestComponent create() {",
-            "      if (testModule == null) {",
-            "        this.testModule = new TestModule();",
-            "      }",
-            "      return new DaggerTestComponent(testModule);",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(moduleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void testSetterMethodWithMoreThanOneArgFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    SimpleComponent build();",
-            "    Builder set(String s, Integer i);",
-            "    Builder set(Number n, Double d);",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustTakeOneArg())
-        .inFile(componentFile)
-        .onLineContaining("Builder set(String s, Integer i);");
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustTakeOneArg())
-        .inFile(componentFile)
-        .onLineContaining("Builder set(Number n, Double d);");
-  }
-
-  @Test
-  public void testInheritedSetterMethodWithMoreThanOneArgFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    SimpleComponent build();",
-            "    Builder set1(String s, Integer i);",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                MSGS.inheritedSetterMethodsMustTakeOneArg(),
-                "set1(java.lang.String,java.lang.Integer)"))
-        .inFile(componentFile)
-        .onLineContaining("interface Builder");
-  }
-
-  @Test
-  public void testSetterReturningNonVoidOrBuilderFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    SimpleComponent build();",
-            "    String set(Integer i);",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustReturnVoidOrBuilder())
-        .inFile(componentFile)
-        .onLineContaining("String set(Integer i);");
-  }
-
-  @Test
-  public void testInheritedSetterReturningNonVoidOrBuilderFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    SimpleComponent build();",
-            "    String set(Integer i);",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                MSGS.inheritedSetterMethodsMustReturnVoidOrBuilder(), "set(java.lang.Integer)"))
-        .inFile(componentFile)
-        .onLineContaining("interface Builder");
-  }
-
-  @Test
-  public void testGenericsOnSetterMethodFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    SimpleComponent build();",
-            "    <T> Builder set(T t);",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.methodsMayNotHaveTypeParameters())
-        .inFile(componentFile)
-        .onLineContaining("<T> Builder set(T t);");
-  }
-
-  @Test
-  public void testGenericsOnInheritedSetterMethodFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    SimpleComponent build();",
-            "    <T> Builder set(T t);",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)"))
-        .inFile(componentFile)
-        .onLineContaining("interface Builder");
-  }
-
-  @Test
-  public void testBindsInstanceNotAllowedOnBothSetterAndParameter() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  abstract String s();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance",
-            "    Builder s(@BindsInstance String s);",
-            "",
-            "    SimpleComponent build();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.bindsInstanceNotAllowedOnBothSetterMethodAndParameter())
-        .inFile(componentFile)
-        .onLineContaining("Builder s(");
-  }
-
-  @Test
-  public void testBindsInstanceNotAllowedOnBothSetterAndParameter_inherited() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  abstract String s();",
-            "",
-            "  interface BuilderParent<B extends BuilderParent> {",
-            "    @BindsInstance",
-            "    B s(@BindsInstance String s);",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends BuilderParent<Builder> {",
-            "    SimpleComponent build();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                MSGS.inheritedBindsInstanceNotAllowedOnBothSetterMethodAndParameter(),
-                "s(java.lang.String)"))
-        .inFile(componentFile)
-        .onLineContaining("Builder extends BuilderParent<Builder>");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentCreatorTest.java b/javatests/dagger/internal/codegen/ComponentCreatorTest.java
deleted file mode 100644
index 6f4ea8d..0000000
--- a/javatests/dagger/internal/codegen/ComponentCreatorTest.java
+++ /dev/null
@@ -1,1253 +0,0 @@
-/*
- * Copyright (C) 2015 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.collect.Sets.immutableEnumSet;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.COMPONENT_BUILDER;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.COMPONENT_FACTORY;
-import static dagger.internal.codegen.ComponentCreatorKind.BUILDER;
-import static dagger.internal.codegen.ComponentCreatorKind.FACTORY;
-import static dagger.internal.codegen.ComponentKind.COMPONENT;
-import static dagger.internal.codegen.ErrorMessages.componentMessagesFor;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for properties of component creators shared by both builders and factories. */
-@RunWith(Parameterized.class)
-public class ComponentCreatorTest extends ComponentCreatorTestHelper {
-  @Parameters(name = "compilerMode={0}, creatorKind={1}")
-  public static Collection<Object[]> parameters() {
-    Set<List<Object>> params =
-        Sets.<Object>cartesianProduct(
-            immutableEnumSet(DEFAULT_MODE, FAST_INIT_MODE),
-            immutableEnumSet(COMPONENT_BUILDER, COMPONENT_FACTORY));
-    return ImmutableList.copyOf(Iterables.transform(params, Collection::toArray));
-  }
-
-  public ComponentCreatorTest(
-      CompilerMode compilerMode, ComponentCreatorAnnotation componentCreatorAnnotation) {
-    super(compilerMode, componentCreatorAnnotation);
-  }
-
-  @Test
-  public void testEmptyCreator() {
-    JavaFileObject injectableTypeFile =
-        JavaFileObjects.forSourceLines(
-            "test.SomeInjectableType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class SomeInjectableType {",
-            "  @Inject SomeInjectableType() {}",
-            "}");
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  SomeInjectableType someInjectableType();",
-            "",
-            "  @Component.Builder",
-            "  static interface Builder {",
-            "     SimpleComponent build();",
-            "  }",
-            "}");
-    JavaFileObject generatedComponent =
-        preprocessedJavaFile(
-            "test.DaggerSimpleComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerSimpleComponent implements SimpleComponent {",
-            "  private static final class Builder implements SimpleComponent.Builder {",
-            "    @Override",
-            "    public SimpleComponent build() {",
-            "      return new DaggerSimpleComponent();",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(injectableTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void testCanInstantiateModulesUserCannotSet() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String string() { return null; }",
-            "}");
-
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  String string();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    JavaFileObject generatedComponent =
-        preprocessedJavaFile(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private final TestModule testModule;",
-            "",
-            "  private DaggerTestComponent(TestModule testModuleParam) {",
-            "    this.testModule = testModuleParam;",
-            "  }",
-            "",
-            "  public static TestComponent.Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static TestComponent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public String string() {",
-            "    return TestModule_StringFactory.string(testModule);",
-            "  }",
-            "",
-            "  private static final class Builder implements TestComponent.Builder {",
-            "    @Override",
-            "    public TestComponent build() {",
-            "      return new DaggerTestComponent(new TestModule());",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation = compile(module, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test
-  public void testMoreThanOneCreatorOfSameTypeFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  @Component.Builder",
-            "  static interface Builder {",
-            "     SimpleComponent build();",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder2 {",
-            "     SimpleComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                componentMessagesFor(COMPONENT).moreThanOne(),
-                process("[test.SimpleComponent.Builder, test.SimpleComponent.Builder2]")))
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testBothBuilderAndFactoryFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  @Component.Builder",
-            "  static interface Builder {",
-            "     SimpleComponent build();",
-            "  }",
-            "",
-            "  @Component.Factory",
-            "  interface Factory {",
-            "     SimpleComponent create();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                componentMessagesFor(COMPONENT).moreThanOne(),
-                "[test.SimpleComponent.Builder, test.SimpleComponent.Factory]"))
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testGenericCreatorTypeFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder<T> {",
-            "     SimpleComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.generics()).inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorNotInComponentFails() {
-    JavaFileObject builder =
-        preprocessedJavaFile(
-            "test.Builder",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component.Builder",
-            "interface Builder {}");
-    Compilation compilation = compile(builder);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.mustBeInComponent()).inFile(builder);
-  }
-
-  @Test
-  public void testCreatorMissingFactoryMethodFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.missingFactoryMethod())
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorWithBindsInstanceNoStaticCreateGenerated() {
-    JavaFileObject componentFile =
-        javaFileBuilder("test.SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.BindsInstance;",
-                "import dagger.Component;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component",
-                "interface SimpleComponent {",
-                "  Object object();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Component.Builder",
-                "  interface Builder {",
-                "    @BindsInstance Builder object(Object object);",
-                "    SimpleComponent build();",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Component.Factory",
-                "  interface Factory {",
-                "    SimpleComponent create(@BindsInstance Object object);",
-                "  }")
-            .addLines("}")
-            .build();
-
-    JavaFileObject generatedComponent =
-        javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.internal.Preconditions;",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private final Object object;",
-                "",
-                "  private DaggerSimpleComponent(Object objectParam) {",
-                "    this.object = objectParam;",
-                "  }",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  public static SimpleComponent.Builder builder() {",
-                "    return new Builder();",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  public static SimpleComponent.Factory factory() {",
-                "    return new Factory();",
-                "  }")
-            .addLines(
-                "", //
-                "  @Override",
-                "  public Object object() {",
-                "    return object;",
-                "  }",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  private static final class Builder implements SimpleComponent.Builder {",
-                "    private Object object;",
-                "",
-                "    @Override",
-                "    public Builder object(Object object) {",
-                "      this.object = Preconditions.checkNotNull(object);",
-                "      return this;",
-                "    }",
-                "",
-                "    @Override",
-                "    public SimpleComponent build() {",
-                "      Preconditions.checkBuilderRequirement(object, Object.class);",
-                "      return new DaggerSimpleComponent(object);",
-                "    }",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  private static final class Factory implements SimpleComponent.Factory {",
-                "    @Override",
-                "    public SimpleComponent create(Object object) {",
-                "      Preconditions.checkNotNull(object);",
-                "      return new DaggerSimpleComponent(object);",
-                "    }",
-                "  }")
-            .addLines("}")
-            .build();
-
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test
-  public void testCreatorWithPrimitiveBindsInstance() {
-    JavaFileObject componentFile =
-        javaFileBuilder("test.SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.BindsInstance;",
-                "import dagger.Component;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component",
-                "interface SimpleComponent {",
-                "  int anInt();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Component.Builder",
-                "  interface Builder {",
-                "    @BindsInstance Builder i(int i);",
-                "    SimpleComponent build();",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Component.Factory",
-                "  interface Factory {",
-                "    SimpleComponent create(@BindsInstance int i);",
-                "  }")
-            .addLines(
-                "}")
-            .build();
-
-    JavaFileObject generatedComponent =
-        javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.internal.Preconditions;",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private final Integer i;",
-                "",
-                "  private DaggerSimpleComponent(Integer iParam) {",
-                "    this.i = iParam;",
-                "  }",
-                "",
-                "  @Override",
-                "  public int anInt() {",
-                "    return i;",
-                "  }",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  private static final class Builder implements SimpleComponent.Builder {",
-                "    private Integer i;",
-                "",
-                "    @Override",
-                "    public Builder i(int i) {",
-                "      this.i = Preconditions.checkNotNull(i);",
-                "      return this;",
-                "    }",
-                "",
-                "    @Override",
-                "    public SimpleComponent build() {",
-                "      Preconditions.checkBuilderRequirement(i, Integer.class);",
-                "      return new DaggerSimpleComponent(i);",
-                "    }",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  private static final class Factory implements SimpleComponent.Factory {",
-                "    @Override",
-                "    public SimpleComponent create(int i) {",
-                "      Preconditions.checkNotNull(i);",
-                "      return new DaggerSimpleComponent(i);",
-                "    }",
-                "  }")
-            .addLines(
-                "}")
-            .build();
-
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void testPrivateCreatorFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  private interface Builder {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.isPrivate()).inFile(componentFile);
-  }
-
-  @Test
-  public void testNonStaticCreatorFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  abstract class Builder {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.mustBeStatic()).inFile(componentFile);
-  }
-
-  @Test
-  public void testNonAbstractCreatorFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  static class Builder {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.mustBeAbstract()).inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorOneConstructorWithArgsFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  static abstract class Builder {",
-            "    Builder(String unused) {}",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.invalidConstructor())
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorMoreThanOneConstructorFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  static abstract class Builder {",
-            "    Builder() {}",
-            "    Builder(String unused) {}",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.invalidConstructor())
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorEnumFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  enum Builder {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.mustBeClassOrInterface())
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testCreatorFactoryMethodReturnsWrongTypeFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    String build();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.factoryMethodMustReturnComponentType())
-        .inFile(componentFile)
-        .onLineContaining(process("String build();"));
-  }
-
-  @Test
-  public void testCreatorSetterForNonBindsInstancePrimitiveFails() {
-    JavaFileObject component =
-        javaFileBuilder("test.TestComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Component;",
-                "",
-                "@Component",
-                "interface TestComponent {",
-                "  Object object();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Component.Builder",
-                "  interface Builder {",
-                "    Builder primitive(long l);",
-                "    TestComponent build();",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Component.Factory",
-                "  interface Factory {",
-                "    TestComponent create(long l);",
-                "  }")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(component);
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContaining(messages.nonBindsInstanceParametersMayNotBePrimitives())
-        .inFile(component)
-        .onLineContaining("(long l)");
-  }
-
-  @Test
-  public void testInheritedBuilderBuildReturnsWrongTypeFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    String build();",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.inheritedFactoryMethodMustReturnComponentType(), process("build")))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void testTwoFactoryMethodsFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    SimpleComponent build();",
-            "    SimpleComponent newSimpleComponent();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(String.format(messages.twoFactoryMethods(), process("build")))
-        .inFile(componentFile)
-        .onLineContaining("SimpleComponent newSimpleComponent();");
-  }
-
-  @Test
-  public void testInheritedTwoFactoryMethodsFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    SimpleComponent build();",
-            "    SimpleComponent newSimpleComponent();",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.inheritedTwoFactoryMethods(), process("build()"), "newSimpleComponent()"))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void testMultipleSettersPerTypeFails() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String s() { return \"\"; }",
-            "}");
-    JavaFileObject componentFile =
-        javaFileBuilder("test.SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Component;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component(modules = TestModule.class)",
-                "abstract class SimpleComponent {",
-                "  abstract String s();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Component.Builder",
-                "  interface Builder {",
-                "    SimpleComponent build();",
-                "    void set1(TestModule s);",
-                "    void set2(TestModule s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Component.Factory",
-                "  interface Factory {",
-                "    SimpleComponent create(TestModule m1, TestModule m2);",
-                "  }")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(moduleFile, componentFile);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(BUILDER)
-            ? "[void test.SimpleComponent.Builder.set1(test.TestModule), "
-                + "void test.SimpleComponent.Builder.set2(test.TestModule)]"
-            : "[test.TestModule m1, test.TestModule m2]";
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.multipleSettersForModuleOrDependencyType(), "test.TestModule", elements))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String s() { return \"\"; }",
-            "}");
-    JavaFileObject componentFile =
-        javaFileBuilder("test.SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Component;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component(modules = TestModule.class)",
-                "abstract class SimpleComponent {",
-                "  abstract String s();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  interface Parent<T> {",
-                "    void set1(T t);",
-                "  }",
-                "",
-                "  @Component.Builder",
-                "  interface Builder extends Parent<TestModule> {",
-                "    SimpleComponent build();",
-                "    void set2(TestModule s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  interface Parent<C, T> {",
-                "    C create(TestModule m1, T t);",
-                "  }",
-                "",
-                "  @Component.Factory",
-                "  interface Factory extends Parent<SimpleComponent, TestModule> {}")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(moduleFile, componentFile);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(BUILDER)
-            ? "[void test.SimpleComponent.Builder.set1(test.TestModule), "
-                + "void test.SimpleComponent.Builder.set2(test.TestModule)]"
-            : "[test.TestModule m1, test.TestModule t]";
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.multipleSettersForModuleOrDependencyType(), "test.TestModule", elements))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void testExtraSettersFails() {
-    JavaFileObject componentFile =
-        javaFileBuilder("test.SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Component;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component(modules = AbstractModule.class)",
-                "abstract class SimpleComponent {")
-            .addLinesIf(
-                BUILDER,
-                "  @Component.Builder",
-                "  interface Builder {",
-                "    SimpleComponent build();",
-                "    void abstractModule(AbstractModule abstractModule);",
-                "    void other(String s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Component.Factory",
-                "  interface Factory {",
-                "    SimpleComponent create(AbstractModule abstractModule, String s);",
-                "  }")
-            .addLines("}")
-            .build();
-    JavaFileObject abstractModule =
-        JavaFileObjects.forSourceLines(
-            "test.AbstractModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class AbstractModule {}");
-    Compilation compilation = compile(componentFile, abstractModule);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(BUILDER)
-            ? "[void test.SimpleComponent.Builder.abstractModule(test.AbstractModule), "
-                + "void test.SimpleComponent.Builder.other(String)]"
-            : "[test.AbstractModule abstractModule, String s]";
-    assertThat(compilation)
-        .hadErrorContaining(String.format(messages.extraSetters(), elements))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void testMissingSettersFail() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  TestModule(String unused) {}",
-            "  @Provides String s() { return null; }",
-            "}");
-    JavaFileObject module2File =
-        JavaFileObjects.forSourceLines(
-            "test.Test2Module",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class Test2Module {",
-            "  @Provides Integer i() { return null; }",
-            "}");
-    JavaFileObject module3File =
-        JavaFileObjects.forSourceLines(
-            "test.Test3Module",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class Test3Module {",
-            "  Test3Module(String unused) {}",
-            "  @Provides Double d() { return null; }",
-            "}");
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = {TestModule.class, Test2Module.class, Test3Module.class},",
-            "           dependencies = OtherComponent.class)",
-            "interface TestComponent {",
-            "  String string();",
-            "  Integer integer();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    TestComponent create();",
-            "  }",
-            "}");
-    JavaFileObject otherComponent =
-        JavaFileObjects.forSourceLines(
-            "test.OtherComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface OtherComponent {}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(moduleFile, module2File, module3File, componentFile, otherComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            // Ignores Test2Module because we can construct it ourselves.
-            // TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies.
-            String.format(
-                messages.missingSetters(),
-                "[test.TestModule, test.Test3Module, test.OtherComponent]"))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject component =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface HasSupertype extends Supertype {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    Supertype build();",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(foo, supertype, component);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType_hasNewMethod() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Bar {",
-            "  @Inject Bar() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject component =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface HasSupertype extends Supertype {",
-            "  Bar bar();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    Supertype build();",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(foo, bar, supertype, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining(
-            process(
-                "test.HasSupertype.Builder.build() returns test.Supertype, but test.HasSupertype "
-                    + "declares additional component method(s): bar(). In order to provide "
-                    + "type-safe access to these methods, override build() to return "
-                    + "test.HasSupertype"))
-        .inFile(component)
-        .onLine(11);
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType_hasNewMethod_factoryMethodInherited() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Bar {",
-            "  @Inject Bar() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject creatorSupertype =
-        preprocessedJavaFile(
-            "test.CreatorSupertype",
-            "package test;",
-            "",
-            "interface CreatorSupertype {",
-            "  Supertype build();",
-            "}");
-
-    JavaFileObject component =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface HasSupertype extends Supertype {",
-            "  Bar bar();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends CreatorSupertype {}",
-            "}");
-
-    Compilation compilation = compile(foo, bar, supertype, creatorSupertype, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining(
-            process(
-                "test.HasSupertype.Builder.build() returns test.Supertype, but test.HasSupertype "
-                    + "declares additional component method(s): bar(). In order to provide "
-                    + "type-safe access to these methods, override build() to return "
-                    + "test.HasSupertype"));
-  }
-
-  @Test
-  public void testGenericsOnFactoryMethodFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    <T> SimpleComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.methodsMayNotHaveTypeParameters())
-        .inFile(componentFile)
-        .onLineContaining(process("<T> SimpleComponent build();"));
-  }
-
-  @Test
-  public void testGenericsOnInheritedFactoryMethodFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    <T> SimpleComponent build();",
-            "  }",
-            "",
-            "  @Component.Builder",
-            "  interface Builder extends Parent {}",
-            "}");
-    Compilation compilation = compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.inheritedMethodsMayNotHaveTypeParameters(), process("<T>build()")))
-        .inFile(componentFile)
-        .onLineContaining(process("interface Builder"));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentCreatorTestHelper.java b/javatests/dagger/internal/codegen/ComponentCreatorTestHelper.java
deleted file mode 100644
index 2ee120e..0000000
--- a/javatests/dagger/internal/codegen/ComponentCreatorTestHelper.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2018 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 dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.ComponentCreatorKind.FACTORY;
-import static dagger.internal.codegen.ErrorMessages.creatorMessagesFor;
-import static java.util.stream.Collectors.joining;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Arrays;
-import java.util.stream.Stream;
-import javax.tools.JavaFileObject;
-
-/**
- * Base class for component creator codegen tests that are written in terms of builders and
- * transformed, either by automatic string processing or using a {@code JavaFileBuilder}, to test
- * factories as well.
- */
-abstract class ComponentCreatorTestHelper {
-
-  private final CompilerMode compilerMode;
-
-  protected final ComponentCreatorKind creatorKind;
-  protected final ErrorMessages.ComponentCreatorMessages messages;
-
-  ComponentCreatorTestHelper(
-      CompilerMode compilerMode, ComponentCreatorAnnotation componentCreatorAnnotation) {
-    this.compilerMode = compilerMode;
-    this.creatorKind = componentCreatorAnnotation.creatorKind();
-    this.messages = creatorMessagesFor(componentCreatorAnnotation);
-  }
-
-  // For tests where code for both builders and factories can be largely equivalent, i.e. when there
-  // is nothing to set, just preprocess the lines to change code written for a builder to code for a
-  // factory.
-  // For more complicated code, use a JavaFileBuilder to add different code depending on the creator
-  // kind.
-
-  /**
-   * Processes the given lines, replacing builder-related names with factory-related names if the
-   * creator kind is {@code FACTORY}.
-   */
-  String process(String... lines) {
-    Stream<String> stream = Arrays.stream(lines);
-    if (creatorKind.equals(FACTORY)) {
-      stream =
-          stream.map(
-              line ->
-                  line.replace("Builder", "Factory")
-                      .replace("builder", "factory")
-                      .replace("build", "create"));
-    }
-    return stream.collect(joining("\n"));
-  }
-
-  /**
-   * Returns a Java file with the {@linkplain #process(String...)} processed} versions of the given
-   * lines.
-   */
-  JavaFileObject preprocessedJavaFile(String fullyQualifiedName, String... lines) {
-    return JavaFileObjects.forSourceString(fullyQualifiedName, process(lines));
-  }
-
-  /** Returns a file builder for the current creator kind. */
-  JavaFileBuilder javaFileBuilder(String qualifiedName) {
-    return new JavaFileBuilder(qualifiedName).withSettings(compilerMode, creatorKind);
-  }
-
-  /** Compiles the given files with the set compiler mode's javacopts. */
-  Compilation compile(JavaFileObject... files) {
-    return daggerCompiler().withOptions(compilerMode.javacopts()).compile(files);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentFactoryTest.java b/javatests/dagger/internal/codegen/ComponentFactoryTest.java
deleted file mode 100644
index 403498b..0000000
--- a/javatests/dagger/internal/codegen/ComponentFactoryTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.COMPONENT_FACTORY;
-import static dagger.internal.codegen.ErrorMessages.creatorMessagesFor;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for {@link dagger.Component.Factory} */
-@RunWith(Parameterized.class)
-public class ComponentFactoryTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ComponentFactoryTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  private static final ErrorMessages.ComponentCreatorMessages MSGS =
-      creatorMessagesFor(COMPONENT_FACTORY);
-
-  @Test
-  public void testUsesParameterNames() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String string() { return null; }",
-            "}");
-
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  String string();",
-            "",
-            "  @Component.Factory",
-            "  interface Factory {",
-            "    TestComponent newTestComponent(TestModule mod);",
-            "  }",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private static final class Factory implements TestComponent.Factory {",
-            "    @Override",
-            "    public TestComponent newTestComponent(TestModule mod) {",
-            "      Preconditions.checkNotNull(mod);",
-            "      return new DaggerTestComponent(mod);",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(moduleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void testSetterMethodFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  @Component.Factory",
-            "  interface Factory {",
-            "    SimpleComponent create();",
-            "    Factory set(String s);",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(String.format(MSGS.twoFactoryMethods(), "create()"))
-        .inFile(componentFile)
-        .onLineContaining("Factory set(String s);");
-  }
-
-  @Test
-  public void testInheritedSetterMethodFails() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "abstract class SimpleComponent {",
-            "  interface Parent {",
-            "    SimpleComponent create();",
-            "    Parent set(String s);",
-            "  }",
-            "",
-            "  @Component.Factory",
-            "  interface Factory extends Parent {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(String.format(MSGS.twoFactoryMethods(), "create()"))
-        .inFile(componentFile)
-        .onLineContaining("interface Factory");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentHierarchyValidationTest.java b/javatests/dagger/internal/codegen/ComponentHierarchyValidationTest.java
deleted file mode 100644
index 19eabac..0000000
--- a/javatests/dagger/internal/codegen/ComponentHierarchyValidationTest.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2016 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {ComponentHierarchyValidator}. */
-@RunWith(JUnit4.class)
-public class ComponentHierarchyValidationTest {
-  @Test
-  public void singletonSubcomponent() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Subcomponent",
-            "interface Child {}");
-
-    Compilation compilation = daggerCompiler().compile(component, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("conflicting scopes");
-    assertThat(compilation).hadErrorContaining("test.Parent also has @Singleton");
-
-    Compilation withoutScopeValidation =
-        daggerCompiler()
-            .withOptions("-Adagger.disableInterComponentScopeValidation=none")
-            .compile(component, subcomponent);
-    assertThat(withoutScopeValidation).succeeded();
-  }
-
-  @Test
-  public void productionComponents_productionScopeImplicitOnBoth() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "  Object productionScopedObject();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Provides;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.ProductionScope;",
-            "",
-            "@ProducerModule",
-            "class ParentModule {",
-            "  @Provides @ProductionScope Object parentScopedObject() { return new Object(); }",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  String productionScopedString();",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.Provides;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.ProductionScope;",
-            "",
-            "@ProducerModule",
-            "class ChildModule {",
-            "  @Provides @ProductionScope String childScopedString() { return new String(); }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().compile(component, subcomponent, parentModule, childModule);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void producerModuleRepeated() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(modules = RepeatedProducerModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject repeatedModule =
-        JavaFileObjects.forSourceLines(
-            "test.RepeatedProducerModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "",
-            "@ProducerModule",
-            "interface RepeatedProducerModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent(modules = RepeatedProducerModule.class)",
-            "interface Child {}");
-    Compilation compilation = daggerCompiler().compile(component, subcomponent, repeatedModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Child repeats @ProducerModules:",
-                "  test.Parent also installs: test.RepeatedProducerModule"))
-        .inFile(component)
-        .onLineContaining("interface Parent");
-  }
-
-  @Test
-  public void factoryMethodForSubcomponentWithBuilder_isNotAllowed() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module(subcomponents = Sub.class)",
-            "class TestModule {",
-            "}");
-
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Sub build();",
-            "  }",
-            "}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface C {",
-            "  Sub newSub();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(module, component, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Components may not have factory methods for subcomponents that define a builder.");
-  }
-
-  @Test
-  public void repeatedModulesWithScopes() {
-    JavaFileObject testScope =
-        JavaFileObjects.forSourceLines(
-            "test.TestScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface TestScope {}");
-    JavaFileObject moduleWithScopedProvides =
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithScopedProvides",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ModuleWithScopedProvides {",
-            "  @Provides",
-            "  @TestScope",
-            "  static Object o() { return new Object(); }",
-            "}");
-    JavaFileObject moduleWithScopedBinds =
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithScopedBinds",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface ModuleWithScopedBinds {",
-            "  @Binds",
-            "  @TestScope",
-            "  Object o(String s);",
-            "}");
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(",
-            "    modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
-            "interface Child {}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(testScope, moduleWithScopedProvides, moduleWithScopedBinds, parent, child);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Child repeats modules with scoped bindings or declarations:",
-                "  - test.Parent also includes:",
-                "    - test.ModuleWithScopedProvides with scopes: @test.TestScope",
-                "    - test.ModuleWithScopedBinds with scopes: @test.TestScope"));
-  }
-
-  @Test
-  public void repeatedModulesWithReusableScope() {
-    JavaFileObject moduleWithScopedProvides =
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithScopedProvides",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Reusable;",
-            "",
-            "@Module",
-            "class ModuleWithScopedProvides {",
-            "  @Provides",
-            "  @Reusable",
-            "  static Object o() { return new Object(); }",
-            "}");
-    JavaFileObject moduleWithScopedBinds =
-        JavaFileObjects.forSourceLines(
-            "test.ModuleWithScopedBinds",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Reusable;",
-            "",
-            "@Module",
-            "interface ModuleWithScopedBinds {",
-            "  @Binds",
-            "  @Reusable",
-            "  Object o(String s);",
-            "}");
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(",
-            "    modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
-            "interface Child {}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(moduleWithScopedProvides, moduleWithScopedBinds, parent, child);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentProcessorTest.java b/javatests/dagger/internal/codegen/ComponentProcessorTest.java
deleted file mode 100644
index 2b79b6f..0000000
--- a/javatests/dagger/internal/codegen/ComponentProcessorTest.java
+++ /dev/null
@@ -1,2769 +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.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.NPE_FROM_COMPONENT_METHOD;
-import static dagger.internal.codegen.GeneratedLines.NPE_FROM_PROVIDES_METHOD;
-
-import com.google.auto.common.MoreElements;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Sets;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.MembersInjector;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.annotation.processing.RoundEnvironment;
-import javax.inject.Inject;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ComponentProcessorTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ComponentProcessorTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test public void doubleBindingFromResolvedModules() {
-    JavaFileObject parent = JavaFileObjects.forSourceLines("test.ParentModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import java.util.List;",
-        "",
-        "@Module",
-        "abstract class ParentModule<A> {",
-        "  @Provides List<A> provideListB(A a) { return null; }",
-        "}");
-    JavaFileObject child = JavaFileObjects.forSourceLines("test.ChildModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "class ChildNumberModule extends ParentModule<Integer> {",
-        "  @Provides Integer provideInteger() { return null; }",
-        "}");
-    JavaFileObject another = JavaFileObjects.forSourceLines("test.AnotherModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import java.util.List;",
-        "",
-        "@Module",
-        "class AnotherModule {",
-        "  @Provides List<Integer> provideListOfInteger() { return null; }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.BadComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.List;",
-        "",
-        "@Component(modules = {ChildNumberModule.class, AnotherModule.class})",
-        "interface BadComponent {",
-        "  List<Integer> listOfInteger();",
-        "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(parent, child, another, componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("java.util.List<java.lang.Integer> is bound multiple times");
-    assertThat(compilation)
-        .hadErrorContaining("@Provides List<Integer> test.ChildNumberModule.provideListB(Integer)");
-    assertThat(compilation)
-        .hadErrorContaining("@Provides List<Integer> test.AnotherModule.provideListOfInteger()");
-  }
-
-  @Test public void privateNestedClassWithWarningThatIsAnErrorInComponent() {
-    JavaFileObject outerClass = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  @Inject OuterClass(InnerClass innerClass) {}",
-        "",
-        "  private static final class InnerClass {",
-        "    @Inject InnerClass() {}",
-        "  }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.BadComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface BadComponent {",
-        "  OuterClass outerClass();",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                compilerMode.javacopts().append("-Adagger.privateMemberValidation=WARNING"))
-            .compile(outerClass, componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private classes");
-  }
-
-  @Test public void simpleComponent() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  SomeInjectableType someInjectableType();",
-        "  Lazy<SomeInjectableType> lazySomeInjectableType();",
-        "  Provider<SomeInjectableType> someInjectableTypeProvider();",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Lazy;",
-                "import dagger.internal.DoubleCheck;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Provider<SomeInjectableType> someInjectableTypeProvider;")
-            .addLines(
-                "  private DaggerSimpleComponent() {}",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public SomeInjectableType someInjectableType() {",
-                "    return new SomeInjectableType();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Lazy<SomeInjectableType> lazySomeInjectableType() {")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return DoubleCheck.lazy(SomeInjectableType_Factory.create());")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    return DoubleCheck.lazy(someInjectableTypeProvider());")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<SomeInjectableType> someInjectableTypeProvider() {")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return SomeInjectableType_Factory.create();")
-            .addLinesIn(
-                FAST_INIT_MODE, //
-                "    Object local = someInjectableTypeProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      someInjectableTypeProvider = (Provider<SomeInjectableType>) local;",
-                "    }",
-                "    return (Provider<SomeInjectableType>) local;")
-            .addLines(
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private Builder() {}",
-                "",
-                "    public SimpleComponent build() {",
-                "      return new DaggerSimpleComponent();",
-                "    }",
-                "  }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) new SomeInjectableType();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test public void componentWithScope() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Singleton;",
-        "",
-        "@Singleton",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "import javax.inject.Singleton;",
-        "",
-        "@Singleton",
-        "@Component",
-        "interface SimpleComponent {",
-        "  SomeInjectableType someInjectableType();",
-        "  Lazy<SomeInjectableType> lazySomeInjectableType();",
-        "  Provider<SomeInjectableType> someInjectableTypeProvider();",
-        "}");
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Object someInjectableType = new MemoizedSentinel();",
-                "  private volatile Provider<SomeInjectableType> someInjectableTypeProvider;")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  private Provider<SomeInjectableType> someInjectableTypeProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.someInjectableTypeProvider =",
-                "        DoubleCheck.provider(SomeInjectableType_Factory.create());",
-                "  }",
-                "")
-            .addLines(
-                "  @Override", //
-                "  public SomeInjectableType someInjectableType() {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    Object local = someInjectableType;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = someInjectableType;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = new SomeInjectableType();",
-                "          someInjectableType =",
-                "              DoubleCheck.reentrantCheck(someInjectableType, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (SomeInjectableType) local;")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return someInjectableTypeProvider.get();")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Lazy<SomeInjectableType> lazySomeInjectableType() {")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return DoubleCheck.lazy(someInjectableTypeProvider);")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    return DoubleCheck.lazy(someInjectableTypeProvider());")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<SomeInjectableType> someInjectableTypeProvider() {")
-            .addLinesIn(
-                FAST_INIT_MODE, //
-                "    Object local = someInjectableTypeProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      someInjectableTypeProvider = (Provider<SomeInjectableType>) local;",
-                "    }",
-                "    return (Provider<SomeInjectableType>) local;")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return someInjectableTypeProvider;")
-            .addLines( //
-                "  }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) DaggerSimpleComponent.this.someInjectableType();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }")
-            .build();
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void simpleComponentWithNesting() {
-    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines("test.OuterType",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterType {",
-        "  static class A {",
-        "    @Inject A() {}",
-        "  }",
-        "  static class B {",
-        "    @Inject A a;",
-        "  }",
-        "  @Component interface SimpleComponent {",
-        "    A a();",
-        "    void inject(B b);",
-        "  }",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerOuterType_SimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerOuterType_SimpleComponent",
-                "    implements OuterType.SimpleComponent {",
-                "  private DaggerOuterType_SimpleComponent() {}",
-                "",
-                "  @Override",
-                "  public OuterType.A a() {",
-                "    return new OuterType.A();",
-                "  }",
-                "",
-                "  @Override",
-                "  public void inject(OuterType.B b) {",
-                "    injectB(b);",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private OuterType.B injectB(OuterType.B instance) {",
-                "    OuterType_B_MembersInjector.injectA(instance, new OuterType.A());",
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(nestedTypesFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerOuterType_SimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void componentWithModule() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A(B b) {}",
-        "}");
-    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
-        "package test;",
-        "",
-        "interface B {}");
-    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class C {",
-        "  @Inject C() {}",
-        "}");
-
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides B b(C c) { return null; }",
-        "}");
-
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "  A a();",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.internal.Preconditions;",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final TestModule testModule;",
-                "",
-                "  private DaggerTestComponent(TestModule testModuleParam) {",
-                "    this.testModule = testModuleParam;",
-                "  }",
-                "",
-                "  private B getB() {",
-                "    return TestModule_BFactory.b(testModule, new C());",
-                "  }",
-                "",
-                "  @Override",
-                "  public A a() {",
-                "    return new A(getB());",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private TestModule testModule;",
-                "",
-                "    public Builder testModule(TestModule testModule) {",
-                "      this.testModule = Preconditions.checkNotNull(testModule);",
-                "      return this;",
-                "    }",
-                "",
-                "    public TestComponent build() {",
-                "      if (testModule == null) {",
-                "        this.testModule = new TestModule();",
-                "      }",
-                "      return new DaggerTestComponent(testModule);",
-                "    }",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, bFile, cFile, moduleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void componentWithAbstractModule() {
-    JavaFileObject aFile =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class A {",
-            "  @Inject A(B b) {}",
-            "}");
-    JavaFileObject bFile =
-        JavaFileObjects.forSourceLines("test.B",
-            "package test;",
-            "",
-            "interface B {}");
-    JavaFileObject cFile =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class C {",
-            "  @Inject C() {}",
-            "}");
-
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Provides static B b(C c) { return null; }",
-            "}");
-
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private B getB() {",
-                "    return TestModule_BFactory.b(new C());",
-                "  }",
-                "",
-                "  @Override",
-                "  public A a() {",
-                "    return new A(getB());",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, bFile, cFile, moduleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void transitiveModuleDeps() {
-    JavaFileObject always = JavaFileObjects.forSourceLines("test.AlwaysIncluded",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "final class AlwaysIncluded {}");
-    JavaFileObject testModule = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = {DepModule.class, AlwaysIncluded.class})",
-        "final class TestModule extends ParentTestModule {}");
-    JavaFileObject parentTest = JavaFileObjects.forSourceLines("test.ParentTestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = {ParentTestIncluded.class, AlwaysIncluded.class})",
-        "class ParentTestModule {}");
-    JavaFileObject parentTestIncluded = JavaFileObjects.forSourceLines("test.ParentTestIncluded",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = AlwaysIncluded.class)",
-        "final class ParentTestIncluded {}");
-    JavaFileObject depModule = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = {RefByDep.class, AlwaysIncluded.class})",
-        "final class DepModule extends ParentDepModule {}");
-    JavaFileObject refByDep = JavaFileObjects.forSourceLines("test.RefByDep",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = AlwaysIncluded.class)",
-        "final class RefByDep extends ParentDepModule {}");
-    JavaFileObject parentDep = JavaFileObjects.forSourceLines("test.ParentDepModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = {ParentDepIncluded.class, AlwaysIncluded.class})",
-        "class ParentDepModule {}");
-    JavaFileObject parentDepIncluded = JavaFileObjects.forSourceLines("test.ParentDepIncluded",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = AlwaysIncluded.class)",
-        "final class ParentDepIncluded {}");
-
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "}");
-    // Generated code includes all includes, but excludes the parent modules.
-    // The "always" module should only be listed once.
-    JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
-        "test.DaggerTestComponent",
-        "package test;",
-        "",
-        "import dagger.internal.Preconditions;",
-        IMPORT_GENERATED_ANNOTATION,
-        "",
-        GENERATED_ANNOTATION,
-        "final class DaggerTestComponent implements TestComponent {",
-        "  static final class Builder {",
-        "",
-        "    @Deprecated",
-        "    public Builder testModule(TestModule testModule) {",
-        "      Preconditions.checkNotNull(testModule)",
-        "      return this;",
-        "    }",
-        "",
-        "    @Deprecated",
-        "    public Builder parentTestIncluded(ParentTestIncluded parentTestIncluded) {",
-        "      Preconditions.checkNotNull(parentTestIncluded)",
-        "      return this;",
-        "    }",
-        "",
-        "    @Deprecated",
-        "    public Builder alwaysIncluded(AlwaysIncluded alwaysIncluded) {",
-        "      Preconditions.checkNotNull(alwaysIncluded)",
-        "      return this;",
-        "    }",
-        "",
-        "    @Deprecated",
-        "    public Builder depModule(DepModule depModule) {",
-        "      Preconditions.checkNotNull(depModule)",
-        "      return this;",
-        "    }",
-        "",
-        "    @Deprecated",
-        "    public Builder parentDepIncluded(ParentDepIncluded parentDepIncluded) {",
-        "      Preconditions.checkNotNull(parentDepIncluded)",
-        "      return this;",
-        "    }",
-        "",
-        "    @Deprecated",
-        "    public Builder refByDep(RefByDep refByDep) {",
-        "      Preconditions.checkNotNull(refByDep)",
-        "      return this;",
-        "    }",
-        "",
-        "    public TestComponent build() {",
-        "      return new DaggerTestComponent();",
-        "    }",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                always,
-                testModule,
-                parentTest,
-                parentTestIncluded,
-                depModule,
-                refByDep,
-                parentDep,
-                parentDepIncluded,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void generatedTransitiveModule() {
-    JavaFileObject rootModule = JavaFileObjects.forSourceLines("test.RootModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = GeneratedModule.class)",
-        "final class RootModule {}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = RootModule.class)",
-        "interface TestComponent {}");
-    assertThat(
-            daggerCompiler().withOptions(compilerMode.javacopts()).compile(rootModule, component))
-        .failed();
-    assertThat(
-            daggerCompiler(
-                    new GeneratingProcessor(
-                        "test.GeneratedModule",
-                        "package test;",
-                        "",
-                        "import dagger.Module;",
-                        "",
-                        "@Module",
-                        "final class GeneratedModule {}"))
-                .compile(rootModule, component))
-        .succeeded();
-  }
-
-  @Test
-  public void generatedModuleInSubcomponent() {
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.ChildComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GeneratedModule.class)",
-            "interface ChildComponent {}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  ChildComponent childComponent();",
-            "}");
-    assertThat(
-            daggerCompiler().withOptions(compilerMode.javacopts()).compile(subcomponent, component))
-        .failed();
-    assertThat(
-            daggerCompiler(
-                    new GeneratingProcessor(
-                        "test.GeneratedModule",
-                        "package test;",
-                        "",
-                        "import dagger.Module;",
-                        "",
-                        "@Module",
-                        "final class GeneratedModule {}"))
-                .compile(subcomponent, component))
-        .succeeded();
-  }
-
-  @Test
-  public void subcomponentNotGeneratedIfNotUsedInGraph() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  String notSubcomponent();",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module(subcomponents = Child.class)",
-            "class ParentModule {",
-            "  @Provides static String notSubcomponent() { return new String(); }",
-            "}");
-
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "}");
-
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "",
-            "  private DaggerParent() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Parent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public String notSubcomponent() {",
-            "    return ParentModule_NotSubcomponentFactory.notSubcomponent();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "",
-            "    private Builder() {}",
-            "",
-            "    @Deprecated",
-            "    public Builder parentModule(ParentModule parentModule) {",
-            "      Preconditions.checkNotNull(parentModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Parent build() {",
-            "      return new DaggerParent();",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(component, module, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test
-  public void testDefaultPackage() {
-    JavaFileObject aClass = JavaFileObjects.forSourceLines("AClass", "class AClass {}");
-    JavaFileObject bClass = JavaFileObjects.forSourceLines("BClass",
-        "import javax.inject.Inject;",
-        "",
-        "class BClass {",
-        "  @Inject BClass(AClass a) {}",
-        "}");
-    JavaFileObject aModule = JavaFileObjects.forSourceLines("AModule",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module class AModule {",
-        "  @Provides AClass aClass() {",
-        "    return new AClass();",
-        "  }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("SomeComponent",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = AModule.class)",
-        "interface SomeComponent {",
-        "  BClass bClass();",
-        "}");
-    assertThat(
-            daggerCompiler()
-                .withOptions(compilerMode.javacopts())
-                .compile(aModule, aClass, bClass, component))
-        .succeeded();
-  }
-
-  @Test public void membersInjection() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject injectedTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectedType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectedType {",
-        "  @Inject SomeInjectableType injectedField;",
-        "  SomeInjectedType() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  void inject(SomeInjectedType instance);",
-        "  SomeInjectedType injectAndReturn(SomeInjectedType instance);",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  @Override",
-                "  public void inject(SomeInjectedType instance) {",
-                "    injectSomeInjectedType(instance);",
-                "  }",
-                "",
-                "  @Override",
-                "  public SomeInjectedType injectAndReturn(SomeInjectedType instance) {",
-                "    return injectSomeInjectedType(instance);",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private SomeInjectedType injectSomeInjectedType(SomeInjectedType instance) {",
-                "    SomeInjectedType_MembersInjector.injectInjectedField(",
-                "        instance, new SomeInjectableType());",
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, injectedTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void componentInjection() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType(SimpleComponent component) {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  SomeInjectableType someInjectableType();",
-        "  Provider<SimpleComponent> selfProvider();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerSimpleComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerSimpleComponent implements SimpleComponent {",
-            "  private Provider<SimpleComponent> simpleComponentProvider;",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  private void initialize() {",
-            "    this.simpleComponentProvider = InstanceFactory.create((SimpleComponent) this);",
-            "  }",
-            "",
-            "  @Override",
-            "  public SomeInjectableType someInjectableType() {",
-            "    return new SomeInjectableType(this)",
-            "  }",
-            "",
-            "  @Override",
-            "  public Provider<SimpleComponent> selfProvider() {",
-            "    return simpleComponentProvider;",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void membersInjectionInsideProvision() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject injectedTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectedType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectedType {",
-        "  @Inject SomeInjectableType injectedField;",
-        "  @Inject SomeInjectedType() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  SomeInjectedType createAndInject();",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerSimpleComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  @Override",
-                "  public SomeInjectedType createAndInject() {",
-                "    return injectSomeInjectedType(",
-                "        SomeInjectedType_Factory.newInstance());",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private SomeInjectedType injectSomeInjectedType(SomeInjectedType instance) {",
-                "    SomeInjectedType_MembersInjector.injectInjectedField(",
-                "        instance, new SomeInjectableType());",
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, injectedTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void componentDependency() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A() {}",
-        "}");
-    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "final class B {",
-        "  @Inject B(Provider<A> a) {}",
-        "}");
-    JavaFileObject aComponentFile = JavaFileObjects.forSourceLines("test.AComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface AComponent {",
-        "  A a();",
-        "}");
-    JavaFileObject bComponentFile = JavaFileObjects.forSourceLines("test.AComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(dependencies = AComponent.class)",
-        "interface BComponent {",
-        "  B b();",
-        "}");
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerBComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerBComponent implements BComponent {")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  private Provider<A> aProvider;")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final AComponent aComponent;",
-                "  private volatile Provider<A> aProvider;",
-                "",
-                "  private DaggerBComponent(AComponent aComponentParam) {",
-                "    this.aComponent = aComponentParam;",
-                "  }",
-                "",
-                "  private Provider<A> getAProvider() {",
-                "    Object local = aProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      aProvider = (Provider<A>) local;",
-                "    }",
-                "    return (Provider<A>) local;",
-                "  }")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(final AComponent aComponentParam) {",
-                "    this.aProvider = new test_AComponent_a(aComponentParam);",
-                "  }")
-            .addLines(
-                "",
-                "  @Override",
-                "  public B b() {")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "    return new B(aProvider);")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    return new B(getAProvider());")
-            .addLines(
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private AComponent aComponent;",
-                "",
-                "    public Builder aComponent(AComponent aComponent) {",
-                "      this.aComponent = Preconditions.checkNotNull(aComponent);",
-                "      return this;",
-                "    }",
-                "",
-                "    public BComponent build() {",
-                "      Preconditions.checkBuilderRequirement(aComponent, AComponent.class);",
-                "      return new DaggerBComponent(aComponent);",
-                "    }",
-                "  }")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  private static class test_AComponent_a implements Provider<A> {",
-                "    private final AComponent aComponent;",
-                "    ",
-                "    test_AComponent_a(AComponent aComponent) {",
-                "        this.aComponent = aComponent;",
-                "    }",
-                "    ",
-                "    @Override()",
-                "    public A get() {",
-                "      return Preconditions.checkNotNull(",
-                "          aComponent.a(), " + NPE_FROM_COMPONENT_METHOD + ");",
-                "    }",
-                "  }",
-                "}")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "          return (T)",
-                "              Preconditions.checkNotNull(",
-                "                  DaggerBComponent.this.aComponent.a(),",
-                "                  " + NPE_FROM_COMPONENT_METHOD + ");",
-                "        default:",
-                "          throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }")
-            .build();
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, bFile, aComponentFile, bComponentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerBComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void moduleNameCollision() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "public final class A {}");
-    JavaFileObject otherAFile = JavaFileObjects.forSourceLines("other.test.A",
-        "package other.test;",
-        "",
-        "public final class A {}");
-
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "public final class TestModule {",
-        "  @Provides A a() { return null; }",
-        "}");
-    JavaFileObject otherModuleFile = JavaFileObjects.forSourceLines("other.test.TestModule",
-        "package other.test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "public final class TestModule {",
-        "  @Provides A a() { return null; }",
-        "}");
-
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {TestModule.class, other.test.TestModule.class})",
-        "interface TestComponent {",
-        "  A a();",
-        "  other.test.A otherA();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private final TestModule testModule;",
-            "  private final other.test.TestModule testModule2;",
-            "",
-            "  private DaggerTestComponent(",
-            "      TestModule testModuleParam,",
-            "      other.test.TestModule testModule2Param) {",
-            "    this.testModule = testModuleParam;",
-            "    this.testModule2 = testModule2Param;",
-            "  }",
-            "",
-            "  @Override",
-            "  public A a() {",
-            "    return TestModule_AFactory.a(testModule);",
-            "  }",
-            "",
-            "  @Override",
-            "  public other.test.A otherA() {",
-            "    return other.test.TestModule_AFactory.a(testModule2);",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private TestModule testModule;",
-            "    private other.test.TestModule testModule2;",
-            "",
-            "    public Builder testModule(TestModule testModule) {",
-            "      this.testModule = Preconditions.checkNotNull(testModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Builder testModule(other.test.TestModule testModule) {",
-            "      this.testModule2 = Preconditions.checkNotNull(testModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public TestComponent build() {",
-            "      if (testModule == null) {",
-            "        this.testModule = new TestModule();",
-            "      }",
-            "      if (testModule2 == null) {",
-            "        this.testModule2 = new other.test.TestModule();",
-            "      }",
-            "      return new DaggerTestComponent(testModule, testModule2);",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, otherAFile, moduleFile, otherModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void ignoresDependencyMethodsFromObject() {
-    JavaFileObject injectedTypeFile =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class InjectedType {",
-            "  @Inject InjectedType(",
-            "      String stringInjection,",
-            "      int intInjection,",
-            "      AComponent aComponent,",
-            "      Class<AComponent> aClass) {}",
-            "}");
-    JavaFileObject aComponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.AComponent",
-            "package test;",
-            "",
-            "class AComponent {",
-            "  String someStringInjection() {",
-            "    return \"injectedString\";",
-            "  }",
-            "",
-            "  int someIntInjection() {",
-            "    return 123;",
-            "  }",
-            "",
-            "  Class<AComponent> someClassInjection() {",
-            "    return AComponent.class;",
-            "  }",
-            "",
-            "  @Override",
-            "  public String toString() {",
-            "    return null;",
-            "  }",
-            "",
-            "  @Override",
-            "  public int hashCode() {",
-            "    return 456;",
-            "  }",
-            "",
-            "  @Override",
-            "  public AComponent clone() {",
-            "    return null;",
-            "  }",
-            "}");
-    JavaFileObject bComponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.AComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = AComponent.class)",
-            "interface BComponent {",
-            "  InjectedType injectedType();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerBComponent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerBComponent implements BComponent {",
-            "  private final AComponent aComponent;",
-            "",
-            "  private DaggerBComponent(AComponent aComponentParam) {",
-            "    this.aComponent = aComponentParam;",
-            "  }",
-            "",
-            "  @Override",
-            "  public InjectedType injectedType() {",
-            "    return new InjectedType(",
-            "        Preconditions.checkNotNull(",
-            "            aComponent.someStringInjection(),",
-            "            \"Cannot return null from a non-@Nullable component method\"),",
-            "        aComponent.someIntInjection(),",
-            "        aComponent,",
-            "        Preconditions.checkNotNull(",
-            "            aComponent.someClassInjection(),",
-            "            \"Cannot return null from a non-@Nullable component method\"));",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectedTypeFile, aComponentFile, bComponentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerBComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void resolutionOrder() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A(B b) {}",
-        "}");
-    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class B {",
-        "  @Inject B(C c) {}",
-        "}");
-    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class C {",
-        "  @Inject C() {}",
-        "}");
-    JavaFileObject xFile = JavaFileObjects.forSourceLines("test.X",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class X {",
-        "  @Inject X(C c) {}",
-        "}");
-
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  A a();",
-        "  C c();",
-        "  X x();",
-        "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private B getB() {",
-                "    return new B(new C());",
-                "  }",
-                "",
-                "  @Override",
-                "  public A a() {",
-                "    return new A(getB());",
-                "  }",
-                "",
-                "  @Override",
-                "  public C c() {",
-                "    return new C();",
-                "  }",
-                "",
-                "  @Override",
-                "  public X x() {",
-                "    return new X(new C());",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, bFile, cFile, xFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void simpleComponent_redundantComponentMethod() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject componentSupertypeAFile = JavaFileObjects.forSourceLines("test.SupertypeA",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SupertypeA {",
-        "  SomeInjectableType someInjectableType();",
-        "}");
-    JavaFileObject componentSupertypeBFile = JavaFileObjects.forSourceLines("test.SupertypeB",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SupertypeB {",
-        "  SomeInjectableType someInjectableType();",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SimpleComponent extends SupertypeA, SupertypeB {",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerSimpleComponent",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerSimpleComponent implements SimpleComponent {",
-            "  private DaggerSimpleComponent() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static SimpleComponent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public SomeInjectableType someInjectableType() {",
-            "    return new SomeInjectableType();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public SimpleComponent build() {",
-            "      return new DaggerSimpleComponent();",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                injectableTypeFile,
-                componentSupertypeAFile,
-                componentSupertypeBFile,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test public void simpleComponent_inheritedComponentMethodDep() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType() {}",
-        "}");
-    JavaFileObject componentSupertype = JavaFileObjects.forSourceLines("test.Supertype",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface Supertype {",
-        "  SomeInjectableType someInjectableType();",
-        "}");
-    JavaFileObject depComponentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface SimpleComponent extends Supertype {",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerSimpleComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerSimpleComponent implements SimpleComponent {",
-            "  @Override",
-            "  public SomeInjectableType someInjectableType() {",
-            "    return new SomeInjectableType();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, componentSupertype, depComponentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void wildcardGenericsRequiresAtProvides() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A() {}",
-        "}");
-    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "final class B<T> {",
-        "  @Inject B(T t) {}",
-        "}");
-    JavaFileObject cFile = JavaFileObjects.forSourceLines("test.C",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "final class C {",
-        "  @Inject C(B<? extends A> bA) {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Lazy;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  C c();",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(aFile, bFile, cFile, componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.B<? extends test.A> cannot be provided without an @Provides-annotated method");
-  }
-
-  // https://github.com/google/dagger/issues/630
-  @Test
-  public void arrayKeyRequiresAtProvides() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  String[] array();",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("String[] cannot be provided without an @Provides-annotated method");
-  }
-
-  @Test
-  public void componentImplicitlyDependsOnGeneratedType() {
-    JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SomeInjectableType {",
-        "  @Inject SomeInjectableType(GeneratedType generatedType) {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface SimpleComponent {",
-        "  SomeInjectableType someInjectableType();",
-        "}");
-    Compilation compilation =
-        daggerCompiler(
-                new GeneratingProcessor(
-                    "test.GeneratedType",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "final class GeneratedType {",
-                    "  @Inject GeneratedType() {}",
-                    "}"))
-            .withOptions(compilerMode.javacopts())
-            .compile(injectableTypeFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation).generatedSourceFile("test.DaggerSimpleComponent");
-  }
-
-  @Test
-  public void componentSupertypeDependsOnGeneratedType() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface SimpleComponent extends SimpleComponentInterface {}");
-    JavaFileObject interfaceFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponentInterface",
-            "package test;",
-            "",
-            "interface SimpleComponentInterface {",
-            "  GeneratedType generatedType();",
-            "}");
-    Compilation compilation =
-        daggerCompiler(
-                new GeneratingProcessor(
-                    "test.GeneratedType",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "final class GeneratedType {",
-                    "  @Inject GeneratedType() {}",
-                    "}"))
-            .withOptions(compilerMode.javacopts())
-            .compile(componentFile, interfaceFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation).generatedSourceFile("test.DaggerSimpleComponent");
-  }
-
-  /**
-   * We warn when generating a {@link MembersInjector} for a type post-hoc (i.e., if Dagger wasn't
-   * invoked when compiling the type). But Dagger only generates {@link MembersInjector}s for types
-   * with {@link Inject @Inject} constructors if they have any injection sites, and it only
-   * generates them for types without {@link Inject @Inject} constructors if they have local
-   * (non-inherited) injection sites. So make sure we warn in only those cases where running the
-   * Dagger processor actually generates a {@link MembersInjector}.
-   */
-  @Test
-  public void unprocessedMembersInjectorNotes() {
-    Compilation compilation =
-        javac()
-            .withOptions(
-                compilerMode
-                    .javacopts()
-                    .append(
-                        "-Xlint:-processing",
-                        "-Adagger.warnIfInjectionFactoryNotGeneratedUpstream=enabled"))
-            .withProcessors(
-                new ElementFilteringComponentProcessor(
-                    Predicates.not(
-                        element ->
-                            MoreElements.getPackage(element)
-                                .getQualifiedName()
-                                .contentEquals("test.inject"))))
-            .compile(
-                JavaFileObjects.forSourceLines(
-                    "test.TestComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component(modules = TestModule.class)",
-                    "interface TestComponent {",
-                    "  void inject(test.inject.NoInjectMemberNoConstructor object);",
-                    "  void inject(test.inject.NoInjectMemberWithConstructor object);",
-                    "  void inject(test.inject.LocalInjectMemberNoConstructor object);",
-                    "  void inject(test.inject.LocalInjectMemberWithConstructor object);",
-                    "  void inject(test.inject.ParentInjectMemberNoConstructor object);",
-                    "  void inject(test.inject.ParentInjectMemberWithConstructor object);",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.TestModule",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "",
-                    "@Module",
-                    "class TestModule {",
-                    "  @Provides static Object object() {",
-                    "    return \"object\";",
-                    "  }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.NoInjectMemberNoConstructor",
-                    "package test.inject;",
-                    "",
-                    "public class NoInjectMemberNoConstructor {",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.NoInjectMemberWithConstructor",
-                    "package test.inject;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class NoInjectMemberWithConstructor {",
-                    "  @Inject NoInjectMemberWithConstructor() {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.LocalInjectMemberNoConstructor",
-                    "package test.inject;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class LocalInjectMemberNoConstructor {",
-                    "  @Inject Object object;",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.LocalInjectMemberWithConstructor",
-                    "package test.inject;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class LocalInjectMemberWithConstructor {",
-                    "  @Inject LocalInjectMemberWithConstructor() {}",
-                    "  @Inject Object object;",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.ParentInjectMemberNoConstructor",
-                    "package test.inject;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class ParentInjectMemberNoConstructor",
-                    "    extends LocalInjectMemberNoConstructor {}"),
-                JavaFileObjects.forSourceLines(
-                    "test.inject.ParentInjectMemberWithConstructor",
-                    "package test.inject;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class ParentInjectMemberWithConstructor",
-                    "    extends LocalInjectMemberNoConstructor {",
-                    "  @Inject ParentInjectMemberWithConstructor() {}",
-                    "}"));
-
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .hadNoteContaining(
-            "Generating a MembersInjector for "
-                + "test.inject.LocalInjectMemberNoConstructor. "
-                + "Prefer to run the dagger processor over that class instead.");
-    assertThat(compilation)
-        .hadNoteContaining(
-            "Generating a MembersInjector for "
-                + "test.inject.LocalInjectMemberWithConstructor. "
-                + "Prefer to run the dagger processor over that class instead.");
-    assertThat(compilation)
-        .hadNoteContaining(
-            "Generating a MembersInjector for "
-                + "test.inject.ParentInjectMemberWithConstructor. "
-                + "Prefer to run the dagger processor over that class instead.");
-    assertThat(compilation).hadNoteCount(3);
-  }
-
-  @Test
-  public void scopeAnnotationOnInjectConstructorNotValid() {
-    JavaFileObject aScope =
-        JavaFileObjects.forSourceLines(
-            "test.AScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface AScope {}");
-    JavaFileObject aClass =
-        JavaFileObjects.forSourceLines(
-            "test.AClass",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class AClass {",
-            "  @Inject @AScope AClass() {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(aScope, aClass);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Scope annotations are not allowed on @Inject constructors")
-        .inFile(aClass)
-        .onLine(6);
-  }
-
-  @Test
-  public void unusedSubcomponents_dontResolveExtraBindingsInParentComponents() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module(subcomponents = Pruned.class)",
-            "class TestModule {}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = TestModule.class)",
-            "interface Parent {}");
-
-    JavaFileObject prunedSubcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Pruned",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Pruned {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Pruned build();",
-            "  }",
-            "",
-            "  Foo foo();",
-            "}");
-    JavaFileObject generated =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private DaggerParent() {",
-            "  }",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Parent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    @Deprecated",
-            "    public Builder testModule(TestModule testModule) {",
-            "      Preconditions.checkNotNull(testModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Parent build() {",
-            "      return new DaggerParent();",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(foo, module, component, prunedSubcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .hasSourceEquivalentTo(generated);
-  }
-
-  @Test
-  public void bindsToDuplicateBinding_bindsKeyIsNotDuplicated() {
-    JavaFileObject firstModule =
-        JavaFileObjects.forSourceLines(
-            "test.FirstModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class FirstModule {",
-            "  @Provides static String first() { return \"first\"; }",
-            "}");
-    JavaFileObject secondModule =
-        JavaFileObjects.forSourceLines(
-            "test.SecondModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class SecondModule {",
-            "  @Provides static String second() { return \"second\"; }",
-            "}");
-    JavaFileObject bindsModule =
-        JavaFileObjects.forSourceLines(
-            "test.BindsModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class BindsModule {",
-            "  @Binds abstract Object bindToDuplicateBinding(String duplicate);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = {FirstModule.class, SecondModule.class, BindsModule.class})",
-            "interface TestComponent {",
-            "  Object notDuplicated();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(firstModule, secondModule, bindsModule, component);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorCount(1);
-    assertThat(compilation)
-        .hadErrorContaining("java.lang.String is bound multiple times")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void nullIncorrectlyReturnedFromNonNullableInlinedProvider() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                JavaFileObjects.forSourceLines(
-                    "test.TestModule",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "",
-                    "@Module",
-                    "public abstract class TestModule {",
-                    "  @Provides static String nonNullableString() { return \"string\"; }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.InjectsMember",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class InjectsMember {",
-                    "  @Inject String member;",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.TestComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component(modules = TestModule.class)",
-                    "interface TestComponent {",
-                    "  String nonNullableString();",
-                    "  void inject(InjectsMember member);",
-                    "}"));
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.TestModule_NonNullableStringFactory")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.TestModule_NonNullableStringFactory",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class TestModule_NonNullableStringFactory",
-                "    implements Factory<String> {",
-                "  @Override",
-                "  public String get() {",
-                "    return nonNullableString();",
-                "  }",
-                "",
-                "  public static String nonNullableString() {",
-                "    return Preconditions.checkNotNull(",
-                "        TestModule.nonNullableString(), " + NPE_FROM_PROVIDES_METHOD + ");",
-                "  }",
-                "}"));
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  @Override",
-                "  public String nonNullableString() {",
-                "    return TestModule_NonNullableStringFactory.nonNullableString());",
-                "  }",
-                "",
-                "  @Override",
-                "  public void inject(InjectsMember member) {",
-                "    injectInjectsMember(member);",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private InjectsMember injectInjectsMember(InjectsMember instance) {",
-                "    InjectsMember_MembersInjector.injectMember(instance,",
-                "        TestModule_NonNullableStringFactory.nonNullableString());",
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void nullCheckingIgnoredWhenProviderReturnsPrimitive() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                JavaFileObjects.forSourceLines(
-                    "test.TestModule",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "",
-                    "@Module",
-                    "public abstract class TestModule {",
-                    "  @Provides static int primitiveInteger() { return 1; }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.InjectsMember",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "public class InjectsMember {",
-                    "  @Inject Integer member;",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.TestComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component(modules = TestModule.class)",
-                    "interface TestComponent {",
-                    "  Integer nonNullableInteger();",
-                    "  void inject(InjectsMember member);",
-                    "}"));
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.TestModule_PrimitiveIntegerFactory")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.TestModule_PrimitiveIntegerFactory",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class TestModule_PrimitiveIntegerFactory",
-                "    implements Factory<Integer> {",
-                "",
-                "  @Override",
-                "  public Integer get() {",
-                "    return primitiveInteger();",
-                "  }",
-                "",
-                "  public static int primitiveInteger() {",
-                "    return TestModule.primitiveInteger();",
-                "  }",
-                "}"));
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  @Override",
-                "  public Integer nonNullableInteger() {",
-                "    return TestModule.primitiveInteger();",
-                "  }",
-                "",
-                "  @Override",
-                "  public void inject(InjectsMember member) {",
-                "    injectInjectsMember(member);",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private InjectsMember injectInjectsMember(InjectsMember instance) {",
-                "    InjectsMember_MembersInjector.injectMember(",
-                "        instance, TestModule.primitiveInteger());",
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void privateMethodUsedOnlyInChildDoesNotUseQualifiedThis() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules=TestModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject testModule =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Provides @Singleton static Number number() {",
-            "    return 3;",
-            "  }",
-            "",
-            "  @Provides static String string(Number number) {",
-            "    return number.toString();",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  String string();",
-            "}");
-
-    JavaFileObject expectedPattern =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private String getString() {",
-            "    return TestModule_StringFactory.string(numberProvider.get());",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, testModule, child);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(expectedPattern);
-  }
-
-  @Test
-  public void componentMethodInChildCallsComponentMethodInParent() {
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  String string();",
-            "}");
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules=TestModule.class)",
-            "interface Parent extends Supertype {",
-            "  Child child();",
-            "}");
-    JavaFileObject testModule =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Provides @Singleton static Number number() {",
-            "    return 3;",
-            "  }",
-            "",
-            "  @Provides static String string(Number number) {",
-            "    return number.toString();",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Child extends Supertype {}");
-
-    JavaFileObject expectedPattern =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private final class ChildImpl implements Child {",
-            "    @Override",
-            "    public String string() {",
-            "      return DaggerParent.this.string();",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(supertype, parent, testModule, child);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(expectedPattern);
-  }
-
-  @Test
-  public void justInTimeAtInjectConstructor_hasGeneratedQualifier() {
-    JavaFileObject injected =
-        JavaFileObjects.forSourceLines(
-            "test.Injected",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Injected {",
-            "  @Inject Injected(@GeneratedQualifier String string) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String unqualified() {",
-            "    return new String();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @GeneratedQualifier",
-            "  static String qualified() {",
-            "    return new String();",
-            "  }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Injected injected();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public Injected injected() {",
-            // Ensure that the qualified @Provides method is used. It's also probably more likely
-            // that if the qualifier type hasn't been generated, a duplicate binding error will be
-            // reported, since the annotation won't be recognized as a qualifier and instead as an
-            // ordinary annotation.
-            "    return new Injected(TestModule_QualifiedFactory.qualified());",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler(
-                new GeneratingProcessor(
-                    "test.GeneratedQualifier",
-                    "package test;",
-                    "",
-                    "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-                    "",
-                    "import java.lang.annotation.Retention;",
-                    "import javax.inject.Qualifier;",
-                    "",
-                    "@Retention(RUNTIME)",
-                    "@Qualifier",
-                    "@interface GeneratedQualifier {}"))
-            .compile(injected, module, component);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void moduleHasGeneratedQualifier() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String unqualified() {",
-            "    return new String();",
-            "  }",
-            "",
-            "  @Provides",
-            "  @GeneratedQualifier",
-            "  static String qualified() {",
-            "    return new String();",
-            "  }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  String unqualified();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public String unqualified() {",
-            // Ensure that the unqualified @Provides method is used. It's also probably more likely
-            // if the qualifier hasn't been generated, a duplicate binding exception will be thrown
-            // since the annotation won't be considered a qualifier
-            "    return TestModule_UnqualifiedFactory.unqualified();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler(
-            new GeneratingProcessor(
-                "test.GeneratedQualifier",
-                "package test;",
-                "",
-                "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-                "",
-                "import java.lang.annotation.Retention;",
-                "import javax.inject.Qualifier;",
-                "",
-                "@Retention(RUNTIME)",
-                "@Qualifier",
-                "@interface GeneratedQualifier {}"))
-            .compile(module, component);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void publicComponentType() {
-    JavaFileObject publicComponent =
-        JavaFileObjects.forSourceLines(
-            "test.PublicComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "public interface PublicComponent {}");
-    Compilation compilation = daggerCompiler().compile(publicComponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerPublicComponent")
-        .hasSourceEquivalentTo(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerPublicComponent",
-                "package test;",
-                "",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "public final class DaggerPublicComponent implements PublicComponent {",
-                "  private DaggerPublicComponent() {}",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static PublicComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  public static final class Builder {",
-                "    private Builder() {}",
-                "",
-                "    public PublicComponent build() {",
-                "      return new DaggerPublicComponent();",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  /**
-   * A {@link ComponentProcessor} that excludes elements using a {@link Predicate}.
-   */
-  private static final class ElementFilteringComponentProcessor extends AbstractProcessor {
-    private final ComponentProcessor componentProcessor = new ComponentProcessor();
-    private final Predicate<? super Element> filter;
-
-    /**
-     * Creates a {@link ComponentProcessor} that only processes elements that match {@code filter}.
-     */
-    public ElementFilteringComponentProcessor(Predicate<? super Element> filter) {
-      this.filter = filter;
-    }
-
-    @Override
-    public synchronized void init(ProcessingEnvironment processingEnv) {
-      super.init(processingEnv);
-      componentProcessor.init(processingEnv);
-    }
-
-    @Override
-    public Set<String> getSupportedAnnotationTypes() {
-      return componentProcessor.getSupportedAnnotationTypes();
-    }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-      return componentProcessor.getSupportedSourceVersion();
-    }
-
-    @Override
-    public Set<String> getSupportedOptions() {
-      return componentProcessor.getSupportedOptions();
-    }
-
-    @Override
-    public boolean process(
-        Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
-      return componentProcessor.process(
-          annotations,
-          new RoundEnvironment() {
-            @Override
-            public boolean processingOver() {
-              return roundEnv.processingOver();
-            }
-
-            @Override
-            public Set<? extends Element> getRootElements() {
-              return Sets.filter(roundEnv.getRootElements(), filter);
-            }
-
-            @Override
-            public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
-              return Sets.filter(roundEnv.getElementsAnnotatedWith(a), filter);
-            }
-
-            @Override
-            public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) {
-              return Sets.filter(roundEnv.getElementsAnnotatedWith(a), filter);
-            }
-
-            @Override
-            public boolean errorRaised() {
-              return roundEnv.errorRaised();
-            }
-          });
-    }
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java b/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java
deleted file mode 100644
index 85e2d7b..0000000
--- a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.NPE_FROM_COMPONENT_METHOD;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ComponentRequirementFieldTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ComponentRequirementFieldTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void bindsInstance() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "import java.util.List;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  int i();",
-            "  List<String> list();",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder i(int i);",
-            "    @BindsInstance Builder list(List<String> list);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final Integer i;",
-                "  private final List<String> list;",
-                "",
-                "  private DaggerTestComponent(Integer iParam, List<String> listParam) {",
-                "    this.i = iParam;",
-                "    this.list = listParam;",
-                "  }",
-                "",
-                "  @Override",
-                "  public int i() {",
-                "    return i;",
-                "  }",
-                "",
-                "  @Override",
-                "  public List<String> list() {",
-                "    return list;",
-                "  }",
-                "",
-                "  private static final class Builder implements TestComponent.Builder {",
-                "    private Integer i;",
-                "    private List<String> list;",
-                "",
-                "    @Override",
-                "    public Builder i(int i) {",
-                "      this.i = Preconditions.checkNotNull(i);",
-                "      return this;",
-                "    }",
-                "",
-                "    @Override",
-                "    public Builder list(List<String> list) {",
-                "      this.list = Preconditions.checkNotNull(list);",
-                "      return this;",
-                "    }",
-                "",
-                "    @Override",
-                "    public TestComponent build() {",
-                "      Preconditions.checkBuilderRequirement(i, Integer.class);",
-                "      Preconditions.checkBuilderRequirement(list, List.class);",
-                "      return new DaggerTestComponent(i, list);",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void instanceModuleMethod() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides int i() { return 0; }",
-            "}");
-    JavaFileObject otherPackageModule =
-        JavaFileObjects.forSourceLines(
-            "other.OtherPackageModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "public class OtherPackageModule {",
-            "  @Provides long l() { return 0L; }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import other.OtherPackageModule;",
-            "",
-            "@Component(modules = {ParentModule.class, OtherPackageModule.class})",
-            "interface TestComponent {",
-            "  int i();",
-            "  long l();",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, otherPackageModule, component);
-    assertThat(compilation).succeeded();
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import other.OtherPackageModule;",
-            "import other.OtherPackageModule_LFactory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private final ParentModule parentModule;",
-            "  private final OtherPackageModule otherPackageModule;",
-            "",
-            "  @Override",
-            "  public int i() {",
-            "    return parentModule.i();",
-            "  }",
-            "",
-            "  @Override",
-            "  public long l() {",
-            "    return OtherPackageModule_LFactory.l(otherPackageModule);",
-            "  }",
-            "}");
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void componentInstances() {
-    JavaFileObject dependency =
-        JavaFileObjects.forSourceLines(
-            "test.Dep",
-            "package test;",
-            "",
-            "interface Dep {",
-            "  String string();",
-            "  Object object();",
-            "}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = Dep.class)",
-            "interface TestComponent {",
-            "  TestComponent self();",
-            "  TestSubcomponent subcomponent();",
-            "",
-            "  Dep dep();",
-            "  String methodOnDep();",
-            "  Object otherMethodOnDep();",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface TestSubcomponent {",
-            "  TestComponent parent();",
-            "  Dep depFromSubcomponent();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(dependency, component, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final Dep dep;",
-                "",
-                "  private DaggerTestComponent(Dep depParam) {",
-                "    this.dep = depParam;",
-                "  }",
-                "",
-                "  @Override",
-                "  public TestComponent self() {",
-                "    return this;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Dep dep() {",
-                "    return dep;",
-                "  }",
-                "",
-                "  @Override",
-                "  public String methodOnDep() {",
-                "    return Preconditions.checkNotNull(",
-                "        dep.string(), " + NPE_FROM_COMPONENT_METHOD + " );",
-                "  }",
-                "",
-                "  @Override",
-                "  public Object otherMethodOnDep() {",
-                "    return Preconditions.checkNotNull(",
-                "        dep.object(), " + NPE_FROM_COMPONENT_METHOD + " );",
-                "  }",
-                "",
-                "  private final class TestSubcomponentImpl implements TestSubcomponent {",
-                "    @Override",
-                "    public TestComponent parent() {",
-                "      return DaggerTestComponent.this;",
-                "    }",
-                "",
-                "    @Override",
-                "    public Dep depFromSubcomponent() {",
-                "      return DaggerTestComponent.this.dep;",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void componentRequirementNeededInFactoryCreationOfSubcomponent() {
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Provides;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides",
-            // intentionally non-static. this needs to require the module when the subcompnent
-            // adds to the Set binding
-            "  Object reliesOnMultibinding(Set<Object> set) { return set; }",
-            "",
-            "  @Provides @IntoSet static Object contribution() { return new Object(); }",
-            "}");
-
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ChildModule {",
-            "  @Provides @IntoSet static Object contribution() { return new Object(); }",
-            "}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface TestComponent {",
-            "  Provider<Object> dependsOnMultibinding();",
-            "  TestSubcomponent subcomponent();",
-            "}");
-
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface TestSubcomponent {",
-            "  Provider<Object> dependsOnMultibinding();",
-            "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final ParentModule parentModule;",
-                "",
-                "  private DaggerTestComponent(ParentModule parentModuleParam) {",
-                "    this.parentModule = parentModuleParam;",
-                "  }",
-                "",
-                "  private final class TestSubcomponentImpl implements TestSubcomponent {",
-                "    private Set<Object> getSetOfObject() {",
-                "      return ImmutableSet.<Object>of(",
-                "          ParentModule_ContributionFactory.contribution(),",
-                "          ChildModule_ContributionFactory.contribution());",
-                "    }",
-                "",
-                "    private Object getObject() {",
-                "      return ParentModule_ReliesOnMultibindingFactory.reliesOnMultibinding(",
-                "          DaggerTestComponent.this.parentModule, getSetOfObject());",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final ParentModule parentModule;",
-                "",
-                "  private DaggerTestComponent(ParentModule parentModuleParam) {",
-                "    this.parentModule = parentModuleParam;",
-                "    initialize(parentModuleParam);",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(final ParentModule parentModuleParam) {",
-                "    this.setOfObjectProvider =",
-                "        SetFactory.<Object>builder(1, 0)",
-                "            .addProvider(ParentModule_ContributionFactory.create())",
-                "            .build();",
-                "    this.reliesOnMultibindingProvider =",
-                "        ParentModule_ReliesOnMultibindingFactory.create(",
-                "            parentModuleParam, setOfObjectProvider);",
-                "  }",
-                "",
-                "  private final class TestSubcomponentImpl implements TestSubcomponent {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    private void initialize() {",
-                "      this.setOfObjectProvider =",
-                "          SetFactory.<Object>builder(2, 0)",
-                "              .addProvider(ParentModule_ContributionFactory.create())",
-                "              .addProvider(ChildModule_ContributionFactory.create())",
-                "              .build();",
-                "      this.reliesOnMultibindingProvider =",
-                "          ParentModule_ReliesOnMultibindingFactory.create(",
-                "              DaggerTestComponent.this.parentModule, setOfObjectProvider);",
-                "    }",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(parentModule, childModule, component, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ComponentValidationTest.java b/javatests/dagger/internal/codegen/ComponentValidationTest.java
deleted file mode 100644
index 169a318..0000000
--- a/javatests/dagger/internal/codegen/ComponentValidationTest.java
+++ /dev/null
@@ -1,356 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ComponentValidationTest {
-  @Test
-  public void componentOnConcreteClass() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "final class NotAComponent {}");
-    Compilation compilation = daggerCompiler().compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void componentOnEnum() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "enum NotAComponent {",
-        "  INSTANCE",
-        "}");
-    Compilation compilation = daggerCompiler().compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void componentOnAnnotation() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "@interface NotAComponent {}");
-    Compilation compilation = daggerCompiler().compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void nonModuleModule() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = Object.class)",
-        "interface NotAComponent {}");
-    Compilation compilation = daggerCompiler().compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("is not annotated with @Module");
-  }
-
-  @Test
-  public void componentWithInvalidModule() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.BadModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class BadModule {",
-            "  @Binds abstract Object noParameters();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.BadComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = BadModule.class)",
-            "interface BadComponent {",
-            "  Object object();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation)
-        .hadErrorContaining("test.BadModule has errors")
-        .inFile(component)
-        .onLine(5);
-  }
-
-  @Test
-  public void attemptToInjectWildcardGenerics() {
-    JavaFileObject testComponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Lazy;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  Lazy<? extends Number> wildcardNumberLazy();",
-            "  Provider<? super Number> wildcardNumberProvider();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(testComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("wildcard type").inFile(testComponent).onLine(9);
-    assertThat(compilation).hadErrorContaining("wildcard type").inFile(testComponent).onLine(10);
-  }
-
-  @Test
-  public void invalidComponentDependencies() {
-    JavaFileObject testComponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = int.class)",
-            "interface TestComponent {}");
-    Compilation compilation = daggerCompiler().compile(testComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("int is not a valid component dependency type");
-  }
-
-  @Test
-  public void invalidComponentModules() {
-    JavaFileObject testComponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = int.class)",
-            "interface TestComponent {}");
-    Compilation compilation = daggerCompiler().compile(testComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("int is not a valid module type");
-  }
-
-  @Test
-  public void moduleInDependencies() {
-    JavaFileObject testModule =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String s() { return null; }",
-            "}");
-    JavaFileObject testComponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = TestModule.class)",
-            "interface TestComponent {}");
-    Compilation compilation = daggerCompiler().compile(testModule, testComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.TestModule is a module, which cannot be a component dependency");
-  }
-
-  @Test
-  public void componentDependencyMustNotCycle_Direct() {
-    JavaFileObject shortLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentShort",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = ComponentShort.class)",
-            "interface ComponentShort {",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(shortLifetime);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ComponentShort contains a cycle in its component dependencies:",
-                "    test.ComponentShort"));
-  }
-
-  @Test
-  public void componentDependencyMustNotCycle_Indirect() {
-    JavaFileObject longLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentLong",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = ComponentMedium.class)",
-            "interface ComponentLong {",
-            "}");
-    JavaFileObject mediumLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentMedium",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = ComponentLong.class)",
-            "interface ComponentMedium {",
-            "}");
-    JavaFileObject shortLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentShort",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(dependencies = ComponentMedium.class)",
-            "interface ComponentShort {",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(longLifetime, mediumLifetime, shortLifetime);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ComponentLong contains a cycle in its component dependencies:",
-                "    test.ComponentLong",
-                "    test.ComponentMedium",
-                "    test.ComponentLong"))
-        .inFile(longLifetime);
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ComponentMedium contains a cycle in its component dependencies:",
-                "    test.ComponentMedium",
-                "    test.ComponentLong",
-                "    test.ComponentMedium"))
-        .inFile(mediumLifetime);
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ComponentShort contains a cycle in its component dependencies:",
-                "    test.ComponentMedium",
-                "    test.ComponentLong",
-                "    test.ComponentMedium",
-                "    test.ComponentShort"))
-        .inFile(shortLifetime);
-  }
-
-  @Test
-  public void abstractModuleWithInstanceMethod() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Provides int i() { return 1; }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  int i();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("TestModule is abstract and has instance @Provides methods")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void abstractModuleWithInstanceMethod_subclassedIsAllowed() {
-    JavaFileObject abstractModule =
-        JavaFileObjects.forSourceLines(
-            "test.AbstractModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class AbstractModule {",
-            "  @Provides int i() { return 1; }",
-            "}");
-    JavaFileObject subclassedModule =
-        JavaFileObjects.forSourceLines(
-            "test.SubclassedModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "class SubclassedModule extends AbstractModule {}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = SubclassedModule.class)",
-            "interface TestComponent {",
-            "  int i();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(abstractModule, subclassedModule, component);
-    assertThat(compilation).succeeded();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ConflictingEntryPointsTest.java b/javatests/dagger/internal/codegen/ConflictingEntryPointsTest.java
deleted file mode 100644
index 7ffd922..0000000
--- a/javatests/dagger/internal/codegen/ConflictingEntryPointsTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ConflictingEntryPointsTest {
-
-  @Test
-  public void covariantType() {
-    JavaFileObject base1 =
-        JavaFileObjects.forSourceLines(
-            "test.Base1", //
-            "package test;",
-            "",
-            "interface Base1 {",
-            "  Long foo();",
-            "}");
-    JavaFileObject base2 =
-        JavaFileObjects.forSourceLines(
-            "test.Base2", //
-            "package test;",
-            "",
-            "interface Base2 {",
-            "  Number foo();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent extends Base1, Base2 {",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder foo(Long foo);",
-            "    @BindsInstance Builder foo(Number foo);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(base1, base2, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "conflicting entry point declarations:",
-                "    Long test.Base1.foo()",
-                "    Number test.Base2.foo()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent ");
-  }
-
-  @Test
-  public void covariantTypeFromGenericSupertypes() {
-    JavaFileObject base1 =
-        JavaFileObjects.forSourceLines(
-            "test.Base1", //
-            "package test;",
-            "",
-            "interface Base1<T> {",
-            "  T foo();",
-            "}");
-    JavaFileObject base2 =
-        JavaFileObjects.forSourceLines(
-            "test.Base2", //
-            "package test;",
-            "",
-            "interface Base2<T> {",
-            "  T foo();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent extends Base1<Long>, Base2<Number> {",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder foo(Long foo);",
-            "    @BindsInstance Builder foo(Number foo);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(base1, base2, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "conflicting entry point declarations:",
-                "    Long test.Base1.foo()",
-                "    Number test.Base2.foo()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent ");
-  }
-
-  @Test
-  public void differentQualifier() {
-    JavaFileObject base1 =
-        JavaFileObjects.forSourceLines(
-            "test.Base1", //
-            "package test;",
-            "",
-            "interface Base1 {",
-            "  Object foo();",
-            "}");
-    JavaFileObject base2 =
-        JavaFileObjects.forSourceLines(
-            "test.Base2", //
-            "package test;",
-            "",
-            "import javax.inject.Named;",
-            "",
-            "interface Base2 {",
-            "  @Named(\"foo\") Object foo();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "import javax.inject.Named;",
-            "",
-            "@Component",
-            "interface TestComponent extends Base1, Base2 {",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder foo(Object foo);",
-            "    @BindsInstance Builder namedFoo(@Named(\"foo\") Object foo);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(base1, base2, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "conflicting entry point declarations:",
-                "    Object test.Base1.foo()",
-                "    @Named(\"foo\") Object test.Base2.foo()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent ");
-  }
-
-  @Test
-  public void sameKey() {
-    JavaFileObject base1 =
-        JavaFileObjects.forSourceLines(
-            "test.Base1", //
-            "package test;",
-            "",
-            "interface Base1 {",
-            "  Object foo();",
-            "}");
-    JavaFileObject base2 =
-        JavaFileObjects.forSourceLines(
-            "test.Base2", //
-            "package test;",
-            "",
-            "interface Base2 {",
-            "  Object foo();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent extends Base1, Base2 {",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder foo(Object foo);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(base1, base2, component);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void sameQualifiedKey() {
-    JavaFileObject base1 =
-        JavaFileObjects.forSourceLines(
-            "test.Base1", //
-            "package test;",
-            "",
-            "import javax.inject.Named;",
-            "",
-            "interface Base1 {",
-            "  @Named(\"foo\") Object foo();",
-            "}");
-    JavaFileObject base2 =
-        JavaFileObjects.forSourceLines(
-            "test.Base2", //
-            "package test;",
-            "",
-            "import javax.inject.Named;",
-            "",
-            "interface Base2 {",
-            "  @Named(\"foo\") Object foo();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.BindsInstance;",
-            "import dagger.Component;",
-            "import javax.inject.Named;",
-            "",
-            "@Component",
-            "interface TestComponent extends Base1, Base2 {",
-            "",
-            "  @Component.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder foo(@Named(\"foo\") Object foo);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(base1, base2, component);
-    assertThat(compilation).succeeded();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/DaggerModuleMethodSubject.java b/javatests/dagger/internal/codegen/DaggerModuleMethodSubject.java
deleted file mode 100644
index 1fcf7bc..0000000
--- a/javatests/dagger/internal/codegen/DaggerModuleMethodSubject.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2016 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.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-import com.google.common.truth.Truth;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-import javax.tools.JavaFileObject;
-
-/** A {@link Truth} subject for testing Dagger module methods. */
-final class DaggerModuleMethodSubject extends Subject<DaggerModuleMethodSubject, String> {
-
-  /** A {@link Truth} subject factory for testing Dagger module methods. */
-  static final class Factory implements Subject.Factory<DaggerModuleMethodSubject, String> {
-
-    /** Starts a clause testing a Dagger {@link Module @Module} method. */
-    static DaggerModuleMethodSubject assertThatModuleMethod(String method) {
-      return assertAbout(daggerModuleMethod())
-          .that(method)
-          .withDeclaration("@Module abstract class %s { %s }");
-    }
-
-    /** Starts a clause testing a Dagger {@link ProducerModule @ProducerModule} method. */
-    static DaggerModuleMethodSubject assertThatProductionModuleMethod(String method) {
-      return assertAbout(daggerModuleMethod())
-          .that(method)
-          .withDeclaration("@ProducerModule abstract class %s { %s }");
-    }
-
-    /** Starts a clause testing a method in an unannotated class. */
-    static DaggerModuleMethodSubject assertThatMethodInUnannotatedClass(String method) {
-      return assertAbout(daggerModuleMethod())
-          .that(method)
-          .withDeclaration("abstract class %s { %s }");
-    }
-
-    static Factory daggerModuleMethod() {
-      return new Factory();
-    }
-
-    private Factory() {}
-
-    @Override
-    public DaggerModuleMethodSubject createSubject(FailureMetadata failureMetadata, String that) {
-      return new DaggerModuleMethodSubject(failureMetadata, that);
-    }
-  }
-
-  private final String actual;
-  private final ImmutableList.Builder<String> imports =
-      new ImmutableList.Builder<String>()
-          .add(
-              // explicitly import Module so it's not ambiguous with java.lang.Module
-              "import dagger.Module;",
-              "import dagger.*;",
-              "import dagger.multibindings.*;",
-              "import dagger.producers.*;",
-              "import java.util.*;",
-              "import javax.inject.*;");
-  private String declaration;
-  private ImmutableList<JavaFileObject> additionalSources = ImmutableList.of();
-
-  private DaggerModuleMethodSubject(FailureMetadata failureMetadata, String subject) {
-    super(failureMetadata, subject);
-    this.actual = subject;
-  }
-
-  /**
-   * Imports classes and interfaces. Note that all types in the following packages are already
-   * imported:<ul>
-   * <li>{@code dagger.*}
-   * <li>{@code dagger.multibindings.*}
-   * <li>(@code dagger.producers.*}
-   * <li>{@code java.util.*}
-   * <li>{@code javax.inject.*}
-   * </ul>
-   */
-  DaggerModuleMethodSubject importing(Class<?>... imports) {
-    return importing(Arrays.asList(imports));
-  }
-
-  /**
-   * Imports classes and interfaces. Note that all types in the following packages are already
-   * imported:<ul>
-   * <li>{@code dagger.*}
-   * <li>{@code dagger.multibindings.*}
-   * <li>(@code dagger.producers.*}
-   * <li>{@code java.util.*}
-   * <li>{@code javax.inject.*}
-   * </ul>
-   */
-  DaggerModuleMethodSubject importing(List<? extends Class<?>> imports) {
-    imports.stream()
-        .map(clazz -> String.format("import %s;", clazz.getCanonicalName()))
-        .forEachOrdered(this.imports::add);
-    return this;
-  }
-
-  /**
-   * Sets the declaration of the module. Must be a string with two {@code %s} parameters. The first
-   * will be replaced with the name of the type, and the second with the method declaration, which
-   * must be within paired braces.
-   */
-  DaggerModuleMethodSubject withDeclaration(String declaration) {
-    this.declaration = declaration;
-    return this;
-  }
-
-  /** Additional source files that must be compiled with the module. */
-  DaggerModuleMethodSubject withAdditionalSources(JavaFileObject... sources) {
-    this.additionalSources = ImmutableList.copyOf(sources);
-    return this;
-  }
-
-  /**
-   * Fails if compiling the module with the method doesn't report an error at the method
-   * declaration whose message contains {@code errorSubstring}.
-   */
-  void hasError(String errorSubstring) {
-    String source = moduleSource();
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule", source);
-    Compilation compilation =
-        daggerCompiler().compile(FluentIterable.from(additionalSources).append(module));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(errorSubstring)
-        .inFile(module)
-        .onLine(methodLine(source));
-  }
-
-  private int methodLine(String source) {
-    String beforeMethod = source.substring(0, source.indexOf(actual));
-    int methodLine = 1;
-    for (int nextNewlineIndex = beforeMethod.indexOf('\n');
-        nextNewlineIndex >= 0;
-        nextNewlineIndex = beforeMethod.indexOf('\n', nextNewlineIndex + 1)) {
-      methodLine++;
-    }
-    return methodLine;
-  }
-
-  private String moduleSource() {
-    StringWriter stringWriter = new StringWriter();
-    PrintWriter writer = new PrintWriter(stringWriter);
-    writer.println("package test;");
-    writer.println();
-    for (String importLine : imports.build()) {
-      writer.println(importLine);
-    }
-    writer.println();
-    writer.printf(declaration, "TestModule", "\n" + actual + "\n");
-    writer.println();
-    return stringWriter.toString();
-  }
-
-}
diff --git a/javatests/dagger/internal/codegen/DelegateBindingExpressionTest.java b/javatests/dagger/internal/codegen/DelegateBindingExpressionTest.java
deleted file mode 100644
index 2f4aecf..0000000
--- a/javatests/dagger/internal/codegen/DelegateBindingExpressionTest.java
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.CompilationSubject;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class DelegateBindingExpressionTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public DelegateBindingExpressionTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  private static final JavaFileObject REGULAR_SCOPED =
-      JavaFileObjects.forSourceLines(
-          "test.RegularScoped",
-          "package test;",
-          "",
-          "import javax.inject.Scope;",
-          "import javax.inject.Inject;",
-          "",
-          "@RegularScoped.CustomScope",
-          "class RegularScoped {",
-          "  @Inject RegularScoped() {}",
-          "",
-          "  @Scope @interface CustomScope {}",
-          "}");
-
-  private static final JavaFileObject REUSABLE_SCOPED =
-      JavaFileObjects.forSourceLines(
-          "test.ReusableScoped",
-          "package test;",
-          "",
-          "import dagger.Reusable;",
-          "import javax.inject.Inject;",
-          "",
-          "@Reusable",
-          "class ReusableScoped {",
-          "  @Inject ReusableScoped() {}",
-          "}");
-
-  private static final JavaFileObject UNSCOPED =
-      JavaFileObjects.forSourceLines(
-          "test.Unscoped",
-          "package test;",
-          "",
-          "import javax.inject.Inject;",
-          "",
-          "class Unscoped {",
-          "  @Inject Unscoped() {}",
-          "}");
-
-  private static final JavaFileObject COMPONENT =
-      JavaFileObjects.forSourceLines(
-          "test.TestComponent",
-          "package test;",
-          "",
-          "import dagger.Component;",
-          "",
-          "@Component(modules = TestModule.class)",
-          "@RegularScoped.CustomScope",
-          "interface TestComponent {",
-          "  @Qualifier(RegularScoped.class)",
-          "  Object regular();",
-          "",
-          "  @Qualifier(ReusableScoped.class)",
-          "  Object reusable();",
-          "",
-          "  @Qualifier(Unscoped.class)",
-          "  Object unscoped();",
-          "}");
-
-  private static final JavaFileObject QUALIFIER =
-      JavaFileObjects.forSourceLines(
-          "test.Qualifier",
-          "package test;",
-          "",
-          "@javax.inject.Qualifier",
-          "@interface Qualifier {",
-          "  Class<?> value();",
-          "}");
-
-  @Test
-  public void toDoubleCheck() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Binds @RegularScoped.CustomScope @Qualifier(RegularScoped.class)",
-            "  Object regular(RegularScoped delegate);",
-            "",
-            "  @Binds @RegularScoped.CustomScope @Qualifier(ReusableScoped.class)",
-            "  Object reusable(ReusableScoped delegate);",
-            "",
-            "  @Binds @RegularScoped.CustomScope @Qualifier(Unscoped.class)",
-            "  Object unscoped(Unscoped delegate);",
-            "}");
-
-    assertThatCompilationWithModule(module)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Object regularScoped = new MemoizedSentinel();",
-                    "  private volatile ReusableScoped reusableScoped;",
-                    "",
-                    "  private RegularScoped getRegularScoped() {",
-                    "    Object local = regularScoped;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = regularScoped;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = new RegularScoped();",
-                    "          regularScoped = DoubleCheck.reentrantCheck(regularScoped, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (RegularScoped) local;",
-                    "  }",
-                    "",
-                    "  private ReusableScoped getReusableScoped() {",
-                    "    Object local = reusableScoped;",
-                    "    if (local == null) {",
-                    "      local = new ReusableScoped();",
-                    "      reusableScoped = (ReusableScoped) local;",
-                    "    }",
-                    "    return (ReusableScoped) local;",
-                    "  }",
-                    "")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @SuppressWarnings(\"unchecked\")",
-                    "  private void initialize() {",
-                    "    this.regularScopedProvider = ",
-                    "        DoubleCheck.provider(RegularScoped_Factory.create());",
-                    "    this.reusableScopedProvider = ",
-                    "        SingleCheck.provider(ReusableScoped_Factory.create());",
-                    "    this.reusableProvider = DoubleCheck.provider(",
-                    "        (Provider) reusableScopedProvider);",
-                    "    this.unscopedProvider = DoubleCheck.provider(",
-                    "        (Provider) Unscoped_Factory.create());",
-                    "  }")
-                .addLines( //
-                    "}")
-                .build());
-  }
-
-  @Test
-  public void toSingleCheck() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Reusable;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Binds @Reusable @Qualifier(RegularScoped.class)",
-            "  Object regular(RegularScoped delegate);",
-            "",
-            "  @Binds @Reusable @Qualifier(ReusableScoped.class)",
-            "  Object reusable(ReusableScoped delegate);",
-            "",
-            "  @Binds @Reusable @Qualifier(Unscoped.class)",
-            "  Object unscoped(Unscoped delegate);",
-            "}");
-
-    assertThatCompilationWithModule(module)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Object regularScoped = new MemoizedSentinel();",
-                    "  private volatile ReusableScoped reusableScoped;",
-                    "",
-                    "  private RegularScoped getRegularScoped() {",
-                    "    Object local = regularScoped;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = regularScoped;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = new RegularScoped();",
-                    "          regularScoped = DoubleCheck.reentrantCheck(regularScoped, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (RegularScoped) local;",
-                    "  }",
-                    "",
-                    "  private ReusableScoped getReusableScoped() {",
-                    "    Object local = reusableScoped;",
-                    "    if (local == null) {",
-                    "      local = new ReusableScoped();",
-                    "      reusableScoped = (ReusableScoped) local;",
-                    "    }",
-                    "    return (ReusableScoped) local;",
-                    "  }",
-                    "")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @SuppressWarnings(\"unchecked\")",
-                    "  private void initialize() {",
-                    "    this.regularScopedProvider = ",
-                    "        DoubleCheck.provider(RegularScoped_Factory.create());",
-                    "    this.reusableScopedProvider = ",
-                    "        SingleCheck.provider(ReusableScoped_Factory.create());",
-                    "    this.unscopedProvider = SingleCheck.provider(",
-                    "        (Provider) Unscoped_Factory.create());",
-                    "  }")
-                .addLines( //
-                    "}")
-                .build());
-  }
-
-  @Test
-  public void toUnscoped() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Binds @Qualifier(RegularScoped.class)",
-            "  Object regular(RegularScoped delegate);",
-            "",
-            "  @Binds @Qualifier(ReusableScoped.class)",
-            "  Object reusable(ReusableScoped delegate);",
-            "",
-            "  @Binds @Qualifier(Unscoped.class)",
-            "  Object unscoped(Unscoped delegate);",
-            "}");
-
-    assertThatCompilationWithModule(module)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Object regularScoped = new MemoizedSentinel();",
-                    "  private volatile ReusableScoped reusableScoped;",
-                    "",
-                    "  private RegularScoped getRegularScoped() {",
-                    "    Object local = regularScoped;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = regularScoped;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = new RegularScoped();",
-                    "          regularScoped = DoubleCheck.reentrantCheck(regularScoped, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (RegularScoped) local;",
-                    "  }",
-                    "",
-                    "  private ReusableScoped getReusableScoped() {",
-                    "    Object local = reusableScoped;",
-                    "    if (local == null) {",
-                    "      local = new ReusableScoped();",
-                    "      reusableScoped = (ReusableScoped) local;",
-                    "    }",
-                    "    return (ReusableScoped) local;",
-                    "  }",
-                    "")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @SuppressWarnings(\"unchecked\")",
-                    "  private void initialize() {",
-                    "    this.regularScopedProvider = ",
-                    "        DoubleCheck.provider(RegularScoped_Factory.create());",
-                    "    this.reusableScopedProvider = ",
-                    "        SingleCheck.provider(ReusableScoped_Factory.create());",
-                    "  }")
-                .addLines( //
-                    "}")
-                .build());
-  }
-
-  @Test
-  public void castNeeded_rawTypes_Provider_get() {
-    JavaFileObject accessibleSupertype =
-        JavaFileObjects.forSourceLines(
-            "other.Supertype",
-            "package other;",
-            "",
-            // accessible from the component, but the subtype is not
-            "public interface Supertype {}");
-    JavaFileObject inaccessibleSubtype =
-        JavaFileObjects.forSourceLines(
-            "other.Subtype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "class Subtype implements Supertype {",
-            "  @Inject Subtype() {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.SupertypeModule",
-            "package other;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "public interface SupertypeModule {",
-            "  @Binds Supertype to(Subtype subtype);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = other.SupertypeModule.class)",
-            "interface TestComponent {",
-            "  other.Supertype supertype();",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(accessibleSupertype, inaccessibleSubtype, module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @SuppressWarnings(\"rawtypes\")",
-                    "  private Provider subtypeProvider;",
-                    "",
-                    "  @SuppressWarnings(\"unchecked\")",
-                    "  private void initialize() {",
-                    "    this.subtypeProvider = DoubleCheck.provider(Subtype_Factory.create());",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Supertype supertype() {",
-                    "    return (Supertype) subtypeProvider.get();",
-                    "  }")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Object subtype = new MemoizedSentinel();",
-                    "",
-                    "  private Object getSubtype() {",
-                    "    Object local = subtype;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = subtype;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = Subtype_Factory.newInstance();",
-                    "          subtype = DoubleCheck.reentrantCheck(subtype, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (Object) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Supertype supertype() {",
-                    "    return (Supertype) getSubtype();",
-                    "  }")
-                .build());
-  }
-
-  @Test
-  public void noCast_rawTypes_Provider_get_toInaccessibleType() {
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "other.Supertype",
-            "package other;",
-            "",
-            "interface Supertype {}");
-    JavaFileObject subtype =
-        JavaFileObjects.forSourceLines(
-            "other.Subtype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "class Subtype implements Supertype {",
-            "  @Inject Subtype() {}",
-            "}");
-    JavaFileObject usesSupertype =
-        JavaFileObjects.forSourceLines(
-            "other.UsesSupertype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesSupertype {",
-            "  @Inject UsesSupertype(Supertype supertype) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.SupertypeModule",
-            "package other;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "public interface SupertypeModule {",
-            "  @Binds Supertype to(Subtype subtype);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = other.SupertypeModule.class)",
-            "interface TestComponent {",
-            "  other.UsesSupertype usesSupertype();",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(supertype, subtype, usesSupertype, module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @SuppressWarnings(\"rawtypes\")",
-                    "  private Provider subtypeProvider;",
-                    "",
-                    "  @Override",
-                    "  public UsesSupertype usesSupertype() {",
-                    //   can't cast the provider.get() to a type that's not accessible
-                    "    return UsesSupertype_Factory.newInstance(subtypeProvider.get());",
-                    "  }",
-                    "}")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Object subtype = new MemoizedSentinel();",
-                    "",
-                    "  private Object getSubtype() {",
-                    "    Object local = subtype;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = subtype;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = Subtype_Factory.newInstance();",
-                    "          subtype = DoubleCheck.reentrantCheck(subtype, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (Object) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public UsesSupertype usesSupertype() {",
-                    "    return UsesSupertype_Factory.newInstance(getSubtype());",
-                    "  }")
-                .build());
-  }
-
-  @Test
-  public void castedToRawType() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Named;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String provideString() { return new String(); }",
-            "",
-            "  @Binds",
-            "  CharSequence charSequence(String string);",
-            "",
-            "  @Binds",
-            "  @Named(\"named\")",
-            "  String namedString(String string);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Named;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<CharSequence> charSequence();",
-            "",
-            "  @Named(\"named\") Provider<String> namedString();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @Override",
-                    "  public Provider<CharSequence> charSequence() {",
-                    "    return (Provider) TestModule_ProvideStringFactory.create();",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<String> namedString() {",
-                    "    return TestModule_ProvideStringFactory.create();",
-                    "  }",
-                    "}")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Provider<String> provideStringProvider;",
-                    "",
-                    "  private Provider<String> getStringProvider() {",
-                    "    Object local = provideStringProvider;",
-                    "    if (local == null) {",
-                    "      local = new SwitchingProvider<>(0);",
-                    "      provideStringProvider = (Provider<String>) local;",
-                    "    }",
-                    "    return (Provider<String>) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<CharSequence> charSequence() {",
-                    "    return (Provider) getStringProvider();",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<String> namedString() {",
-                    "    return getStringProvider();",
-                    "  }",
-                    "",
-                    "  private final class SwitchingProvider<T> implements Provider<T> {",
-                    "    @SuppressWarnings(\"unchecked\")",
-                    "    @Override",
-                    "    public T get() {",
-                    "      switch (id) {",
-                    "        case 0:",
-                    "            return (T) TestModule_ProvideStringFactory.provideString();",
-                    "        default:",
-                    "            throw new AssertionError(id);",
-                    "      }",
-                    "    }",
-                    "  }")
-                .build());
-  }
-
-  @Test
-  public void doubleBinds() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String provideString() { return new String(); }",
-            "",
-            "  @Binds",
-            "  CharSequence charSequence(String string);",
-            "",
-            "  @Binds",
-            "  Object object(CharSequence charSequence);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Named;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<CharSequence> charSequence();",
-            "  Provider<Object> object();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @Override",
-                    "  public Provider<CharSequence> charSequence() {",
-                    "    return (Provider) TestModule_ProvideStringFactory.create();",
-                    "  }",
-                    "  @Override",
-                    "  public Provider<Object> object() {",
-                    "    return (Provider) TestModule_ProvideStringFactory.create();",
-                    "  }",
-                    "}")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Provider<String> provideStringProvider;",
-                    "",
-                    "  private Provider<String> getStringProvider() {",
-                    "    Object local = provideStringProvider;",
-                    "    if (local == null) {",
-                    "      local = new SwitchingProvider<>(0);",
-                    "      provideStringProvider = (Provider<String>) local;",
-                    "    }",
-                    "    return (Provider<String>) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<CharSequence> charSequence() {",
-                    "    return (Provider) getStringProvider();",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<Object> object() {",
-                    "    return (Provider) getStringProvider();",
-                    "  }",
-                    "",
-                    "  private final class SwitchingProvider<T> implements Provider<T> {",
-                    "    @SuppressWarnings(\"unchecked\")",
-                    "    @Override",
-                    "    public T get() {",
-                    "      switch (id) {",
-                    "        case 0:",
-                    "            return (T) TestModule_ProvideStringFactory.provideString();",
-                    "        default:",
-                    "            throw new AssertionError(id);",
-                    "      }",
-                    "    }",
-                    "  }")
-                .build());
-  }
-
-  @Test
-  public void inlineFactoryOfInacessibleType() {
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "other.Supertype", "package other;", "", "public interface Supertype {}");
-    JavaFileObject injectableSubtype =
-        JavaFileObjects.forSourceLines(
-            "other.Subtype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class Subtype implements Supertype {",
-            // important: this doesn't have any dependencies and therefore the factory will be able
-            // to be referenced with an inline Subtype_Factory.create()
-            "  @Inject Subtype() {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.TestModule",
-            "package other;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "public interface TestModule {",
-            "  @Binds Supertype to(Subtype subtype);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.RequestsSubtypeAsProvider",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = other.TestModule.class)",
-            "interface RequestsSubtypeAsProvider {",
-            "  Provider<other.Supertype> supertypeProvider();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(supertype, injectableSubtype, module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerRequestsSubtypeAsProvider")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerRequestsSubtypeAsProvider")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerRequestsSubtypeAsProvider",
-                    "    implements RequestsSubtypeAsProvider {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  @Override",
-                    "  public Provider<Supertype> supertypeProvider() {",
-                    "    return (Provider) Subtype_Factory.create();",
-                    "  }",
-                    "}")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile Provider subtypeProvider;",
-                    "",
-                    "  private Provider getSubtypeProvider() {",
-                    "    Object local = subtypeProvider;",
-                    "    if (local == null) {",
-                    "      local = new SwitchingProvider<>(0);",
-                    "      subtypeProvider = (Provider) local;",
-                    "    }",
-                    "    return (Provider) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<Supertype> supertypeProvider() {",
-                    "    return getSubtypeProvider();",
-                    "  }",
-                    "",
-                    "  private final class SwitchingProvider<T> implements Provider<T> {",
-                    "    @SuppressWarnings(\"unchecked\")",
-                    "    @Override",
-                    "    public T get() {",
-                    "      switch (id) {",
-                    "        case 0: return (T) Subtype_Factory.newInstance();",
-                    "        default: throw new AssertionError(id);",
-                    "      }",
-                    "    }",
-                    "  }")
-                .build());
-  }
-
-  @Test
-  public void providerWhenBindsScopeGreaterThanDependencyScope() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Reusable;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "public abstract class TestModule {",
-            "  @Reusable",
-            "  @Provides",
-            "  static String provideString() {",
-            "    return \"\";",
-            "  }",
-            "",
-            "  @Binds",
-            "  @Singleton",
-            "  abstract Object bindString(String str);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "import javax.inject.Provider;",
-            "",
-            "@Singleton",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<Object> getObject();",
-            "}");
-
-    Compilation compilation = daggerCompiler()
-        .withOptions(compilerMode.javacopts())
-        .compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            compilerMode
-                .javaFileBuilder("test.DaggerTestComponent")
-                .addLines(
-                    "package test;",
-                    "",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerTestComponent implements TestComponent {")
-                .addLinesIn(
-                    DEFAULT_MODE,
-                    "  private Provider<String> provideStringProvider;",
-                    "  private Provider<Object> bindStringProvider;",
-                    "",
-                    "  @SuppressWarnings(\"unchecked\")",
-                    "  private void initialize() {",
-                    "    this.provideStringProvider =",
-                    "        SingleCheck.provider(TestModule_ProvideStringFactory.create());",
-                    "    this.bindStringProvider =",
-                    "        DoubleCheck.provider((Provider) provideStringProvider);",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<Object> getObject() {",
-                    "    return bindStringProvider;",
-                    "  }",
-                    "}")
-                .addLinesIn(
-                    FAST_INIT_MODE,
-                    "  private volatile String string;",
-                    "  private volatile Object object = new MemoizedSentinel();",
-                    "  private volatile Provider<Object> bindStringProvider;",
-                    "",
-                    "  private String getString() {",
-                    "    Object local = string;",
-                    "    if (local == null) {",
-                    "      local = TestModule_ProvideStringFactory.provideString();",
-                    "      string = (String) local;",
-                    "    }",
-                    "    return (String) local;",
-                    "  }",
-                    "",
-                    "  private Object getObject2() {",
-                    "    Object local = object;",
-                    "    if (local instanceof MemoizedSentinel) {",
-                    "      synchronized (local) {",
-                    "        local = object;",
-                    "        if (local instanceof MemoizedSentinel) {",
-                    "          local = getString();",
-                    "          object = DoubleCheck.reentrantCheck(object, local);",
-                    "        }",
-                    "      }",
-                    "    }",
-                    "    return (Object) local;",
-                    "  }",
-                    "",
-                    "  @Override",
-                    "  public Provider<Object> getObject() {",
-                    "    Object local = bindStringProvider;",
-                    "    if (local == null) {",
-                    "      local = new SwitchingProvider<>(0);",
-                    "      bindStringProvider = (Provider<Object>) local;",
-                    "    }",
-                    "    return (Provider<Object>) local;",
-                    "  }",
-                    "",
-                    "  private final class SwitchingProvider<T> implements Provider<T> {",
-                    "    @SuppressWarnings(\"unchecked\")",
-                    "    @Override",
-                    "    public T get() {",
-                    "      switch (id) {",
-                    "        case 0: return (T) DaggerTestComponent.this.getObject2();",
-                    "        default: throw new AssertionError(id);",
-                    "      }",
-                    "    }",
-                    "  }")
-                .build());
-  }
-
-  private CompilationSubject assertThatCompilationWithModule(JavaFileObject module) {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                module,
-                COMPONENT,
-                QUALIFIER,
-                REGULAR_SCOPED,
-                REUSABLE_SCOPED,
-                UNSCOPED);
-    assertThat(compilation).succeeded();
-    return assertThat(compilation);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java b/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java
deleted file mode 100644
index 4a4e0a5..0000000
--- a/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.endsWithMessage;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.regex.Pattern;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DependencyCycleValidationTest {
-  private static final JavaFileObject SIMPLE_CYCLIC_DEPENDENCY =
-      JavaFileObjects.forSourceLines(
-          "test.Outer",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Component;",
-          "import dagger.Module;",
-          "import dagger.Provides;",
-          "import javax.inject.Inject;",
-          "",
-          "final class Outer {",
-          "  static class A {",
-          "    @Inject A(C cParam) {}",
-          "  }",
-          "",
-          "  static class B {",
-          "    @Inject B(A aParam) {}",
-          "  }",
-          "",
-          "  static class C {",
-          "    @Inject C(B bParam) {}",
-          "  }",
-          "",
-          "  @Module",
-          "  interface MModule {",
-          "    @Binds Object object(C c);",
-          "  }",
-          "",
-          "  @Component",
-          "  interface CComponent {",
-          "    C getC();",
-          "  }",
-          "}");
-
-  @Test
-  public void cyclicDependency() {
-    Compilation compilation = daggerCompiler().compile(SIMPLE_CYCLIC_DEPENDENCY);
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.Outer.C is injected at",
-                "        test.Outer.A(cParam)",
-                "    test.Outer.A is injected at",
-                "        test.Outer.B(aParam)",
-                "    test.Outer.B is injected at",
-                "        test.Outer.C(bParam)",
-                "    test.Outer.C is provided at",
-                "        test.Outer.CComponent.getC()"))
-        .inFile(SIMPLE_CYCLIC_DEPENDENCY)
-        .onLineContaining("interface CComponent");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void cyclicDependencyWithModuleBindingValidation() {
-    // Cycle errors should not show a dependency trace to an entry point when doing full binding
-    // graph validation. So ensure that the message doesn't end with "test.Outer.C is provided at
-    // test.Outer.CComponent.getC()", as the previous test's message does.
-    Pattern moduleBindingValidationError =
-        endsWithMessage(
-            "Found a dependency cycle:",
-            "    test.Outer.C is injected at",
-            "        test.Outer.A(cParam)",
-            "    test.Outer.A is injected at",
-            "        test.Outer.B(aParam)",
-            "    test.Outer.B is injected at",
-            "        test.Outer.C(bParam)");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(SIMPLE_CYCLIC_DEPENDENCY);
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(moduleBindingValidationError)
-        .inFile(SIMPLE_CYCLIC_DEPENDENCY)
-        .onLineContaining("interface MModule");
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(moduleBindingValidationError)
-        .inFile(SIMPLE_CYCLIC_DEPENDENCY)
-        .onLineContaining("interface CComponent");
-
-    assertThat(compilation).hadErrorCount(2);
-  }
-
-  @Test public void cyclicDependencyNotIncludingEntryPoint() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  static class A {",
-            "    @Inject A(C cParam) {}",
-            "  }",
-            "",
-            "  static class B {",
-            "    @Inject B(A aParam) {}",
-            "  }",
-            "",
-            "  static class C {",
-            "    @Inject C(B bParam) {}",
-            "  }",
-            "",
-            "  static class D {",
-            "    @Inject D(C cParam) {}",
-            "  }",
-            "",
-            "  @Component",
-            "  interface DComponent {",
-            "    D getD();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.Outer.C is injected at",
-                "        test.Outer.A(cParam)",
-                "    test.Outer.A is injected at",
-                "        test.Outer.B(aParam)",
-                "    test.Outer.B is injected at",
-                "        test.Outer.C(bParam)",
-                "    test.Outer.C is injected at",
-                "        test.Outer.D(cParam)",
-                "    test.Outer.D is provided at",
-                "        test.Outer.DComponent.getD()"))
-        .inFile(component)
-        .onLineContaining("interface DComponent");
-  }
-
-  @Test
-  public void cyclicDependencyNotBrokenByMapBinding() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  static class A {",
-            "    @Inject A(Map<String, C> cMap) {}",
-            "  }",
-            "",
-            "  static class B {",
-            "    @Inject B(A aParam) {}",
-            "  }",
-            "",
-            "  static class C {",
-            "    @Inject C(B bParam) {}",
-            "  }",
-            "",
-            "  @Component(modules = CModule.class)",
-            "  interface CComponent {",
-            "    C getC();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class CModule {",
-            "    @Provides @IntoMap",
-            "    @StringKey(\"C\")",
-            "    static C c(C c) {",
-            "      return c;",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.Outer.C is injected at",
-                "        test.Outer.CModule.c(c)",
-                "    java.util.Map<java.lang.String,test.Outer.C> is injected at",
-                "        test.Outer.A(cMap)",
-                "    test.Outer.A is injected at",
-                "        test.Outer.B(aParam)",
-                "    test.Outer.B is injected at",
-                "        test.Outer.C(bParam)",
-                "    test.Outer.C is provided at",
-                "        test.Outer.CComponent.getC()"))
-        .inFile(component)
-        .onLineContaining("interface CComponent");
-  }
-
-  @Test
-  public void cyclicDependencyWithSetBinding() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  static class A {",
-            "    @Inject A(Set<C> cSet) {}",
-            "  }",
-            "",
-            "  static class B {",
-            "    @Inject B(A aParam) {}",
-            "  }",
-            "",
-            "  static class C {",
-            "    @Inject C(B bParam) {}",
-            "  }",
-            "",
-            "  @Component(modules = CModule.class)",
-            "  interface CComponent {",
-            "    C getC();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class CModule {",
-            "    @Provides @IntoSet",
-            "    static C c(C c) {",
-            "      return c;",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.Outer.C is injected at",
-                "        test.Outer.CModule.c(c)",
-                "    java.util.Set<test.Outer.C> is injected at",
-                "        test.Outer.A(cSet)",
-                "    test.Outer.A is injected at",
-                "        test.Outer.B(aParam)",
-                "    test.Outer.B is injected at",
-                "        test.Outer.C(bParam)",
-                "    test.Outer.C is provided at",
-                "        test.Outer.CComponent.getC()"))
-        .inFile(component)
-        .onLineContaining("interface CComponent");
-  }
-
-  @Test
-  public void falsePositiveCyclicDependencyIndirectionDetected() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class Outer {",
-            "  static class A {",
-            "    @Inject A(C cParam) {}",
-            "  }",
-            "",
-            "  static class B {",
-            "    @Inject B(A aParam) {}",
-            "  }",
-            "",
-            "  static class C {",
-            "    @Inject C(B bParam) {}",
-            "  }",
-            "",
-            "  static class D {",
-            "    @Inject D(Provider<C> cParam) {}",
-            "  }",
-            "",
-            "  @Component",
-            "  interface DComponent {",
-            "    D getD();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.Outer.C is injected at",
-                "        test.Outer.A(cParam)",
-                "    test.Outer.A is injected at",
-                "        test.Outer.B(aParam)",
-                "    test.Outer.B is injected at",
-                "        test.Outer.C(bParam)",
-                "    javax.inject.Provider<test.Outer.C> is injected at",
-                "        test.Outer.D(cParam)",
-                "    test.Outer.D is provided at",
-                "        test.Outer.DComponent.getD()"))
-        .inFile(component)
-        .onLineContaining("interface DComponent");
-  }
-
-  @Test
-  public void cyclicDependencyInSubcomponents() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Parent {",
-            "  Child.Builder child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = CycleModule.class)",
-            "interface Child {",
-            "  Grandchild.Builder grandchild();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "}");
-    JavaFileObject grandchild =
-        JavaFileObjects.forSourceLines(
-            "test.Grandchild",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Grandchild {",
-            "  String entry();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Grandchild build();",
-            "  }",
-            "}");
-    JavaFileObject cycleModule =
-        JavaFileObjects.forSourceLines(
-            "test.CycleModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class CycleModule {",
-            "  @Provides static Object object(String string) {",
-            "    return string;",
-            "  }",
-            "",
-            "  @Provides static String string(Object object) {",
-            "    return object.toString();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, child, grandchild, cycleModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    java.lang.String is injected at",
-                "        test.CycleModule.object(string)",
-                "    java.lang.Object is injected at",
-                "        test.CycleModule.string(object)",
-                "    java.lang.String is provided at",
-                "        test.Grandchild.entry()"))
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-
-  @Test
-  public void cyclicDependencyInSubcomponentsWithChildren() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Parent {",
-            "  Child.Builder child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = CycleModule.class)",
-            "interface Child {",
-            "  String entry();",
-            "",
-            "  Grandchild.Builder grandchild();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "}");
-    // Grandchild has no entry point that depends on the cycle. http://b/111317986
-    JavaFileObject grandchild =
-        JavaFileObjects.forSourceLines(
-            "test.Grandchild",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Grandchild {",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Grandchild build();",
-            "  }",
-            "}");
-    JavaFileObject cycleModule =
-        JavaFileObjects.forSourceLines(
-            "test.CycleModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class CycleModule {",
-            "  @Provides static Object object(String string) {",
-            "    return string;",
-            "  }",
-            "",
-            "  @Provides static String string(Object object) {",
-            "    return object.toString();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, child, grandchild, cycleModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    java.lang.String is injected at",
-                "        test.CycleModule.object(string)",
-                "    java.lang.Object is injected at",
-                "        test.CycleModule.string(object)",
-                "    java.lang.String is provided at",
-                "        test.Child.entry() [test.Parent → test.Child]"))
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-
-  @Test
-  public void circularBindsMethods() {
-    JavaFileObject qualifier =
-        JavaFileObjects.forSourceLines(
-            "test.SomeQualifier",
-            "package test;",
-            "",
-            "import javax.inject.Qualifier;",
-            "",
-            "@Qualifier @interface SomeQualifier {}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Binds abstract Object bindUnqualified(@SomeQualifier Object qualified);",
-            "  @Binds @SomeQualifier abstract Object bindQualified(Object unqualified);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Object unqualified();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(qualifier, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    java.lang.Object is injected at",
-                "        test.TestModule.bindQualified(unqualified)",
-                "    @test.SomeQualifier java.lang.Object is injected at",
-                "        test.TestModule.bindUnqualified(qualified)",
-                "    java.lang.Object is provided at",
-                "        test.TestComponent.unqualified()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void selfReferentialBinds() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Binds abstract Object bindToSelf(Object sameKey);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Object selfReferential();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    java.lang.Object is injected at",
-                "        test.TestModule.bindToSelf(sameKey)",
-                "    java.lang.Object is provided at",
-                "        test.TestComponent.selfReferential()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void cycleFromMembersInjectionMethod_WithSameKeyAsMembersInjectionMethod() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class A {",
-            "  @Inject A() {}",
-            "  @Inject B b;",
-            "}");
-    JavaFileObject b =
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class B {",
-            "  @Inject B() {}",
-            "  @Inject A a;",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.CycleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface CycleComponent {",
-            "  void inject(A a);",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(a, b, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "Found a dependency cycle:",
-                "    test.B is injected at",
-                "        test.A.b",
-                "    test.A is injected at",
-                "        test.B.a",
-                "    test.B is injected at",
-                "        test.A.b",
-                "    test.A is injected at",
-                "        test.CycleComponent.inject(test.A)"))
-        .inFile(component)
-        .onLineContaining("interface CycleComponent");
-  }
-
-  @Test
-  public void longCycleMaskedByShortBrokenCycles() {
-    JavaFileObject cycles =
-        JavaFileObjects.forSourceLines(
-            "test.Cycles",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "import dagger.Component;",
-            "",
-            "final class Cycles {",
-            "  static class A {",
-            "    @Inject A(Provider<A> aProvider, B b) {}",
-            "  }",
-            "",
-            "  static class B {",
-            "    @Inject B(Provider<B> bProvider, A a) {}",
-            "  }",
-            "",
-            "  @Component",
-            "  interface C {",
-            "    A a();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(cycles);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Found a dependency cycle:")
-        .inFile(cycles)
-        .onLineContaining("interface C");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/DiagnosticFormattingTest.java b/javatests/dagger/internal/codegen/DiagnosticFormattingTest.java
deleted file mode 100644
index a2da92f..0000000
--- a/javatests/dagger/internal/codegen/DiagnosticFormattingTest.java
+++ /dev/null
@@ -1,32 +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.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DiagnosticFormattingTest {
-  @Test public void stripCommonTypePrefixes() {
-    String typeName = "com.google.common.collect.ImmutableList<java.lang.Boolean>";
-    assertThat(DiagnosticFormatting.stripCommonTypePrefixes(typeName))
-        .isEqualTo("ImmutableList<Boolean>");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java b/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java
deleted file mode 100644
index 14a6fb9..0000000
--- a/javatests/dagger/internal/codegen/DuplicateBindingsValidationTest.java
+++ /dev/null
@@ -1,1083 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-import static org.junit.Assume.assumeFalse;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class DuplicateBindingsValidationTest {
-
-  @Parameters(name = "fullBindingGraphValidation={0}")
-  public static ImmutableList<Object[]> parameters() {
-    return ImmutableList.copyOf(new Object[][] {{false}, {true}});
-  }
-
-  private final boolean fullBindingGraphValidation;
-
-  public DuplicateBindingsValidationTest(boolean fullBindingGraphValidation) {
-    this.fullBindingGraphValidation = fullBindingGraphValidation;
-  }
-
-  @Test public void duplicateExplicitBindings_ProvidesAndComponentProvision() {
-    assumeFalse(fullBindingGraphValidation);
-
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.Outer",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "final class Outer {",
-        "  interface A {}",
-        "",
-        "  interface B {}",
-        "",
-        "  @Module",
-        "  static class AModule {",
-        "    @Provides String provideString() { return \"\"; }",
-        "    @Provides A provideA(String s) { return new A() {}; }",
-        "  }",
-        "",
-        "  @Component(modules = AModule.class)",
-        "  interface Parent {",
-        "    A getA();",
-        "  }",
-        "",
-        "  @Module",
-        "  static class BModule {",
-        "    @Provides B provideB(A a) { return new B() {}; }",
-        "  }",
-        "",
-        "  @Component(dependencies = Parent.class, modules = { BModule.class, AModule.class})",
-        "  interface Child {",
-        "    B getB();",
-        "  }",
-        "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Outer.A is bound multiple times:",
-                "    @Provides test.Outer.A test.Outer.AModule.provideA(String)",
-                "    test.Outer.A test.Outer.Parent.getA()"))
-        .inFile(component)
-        .onLineContaining("interface Child");
-  }
-
-  @Test public void duplicateExplicitBindings_TwoProvidesMethods() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  interface A {}",
-            "",
-            "  static class B {",
-            "    @Inject B(A a) {}",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module1 {",
-            "    @Provides A provideA1() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module2 {",
-            "    @Provides String provideString() { return \"\"; }",
-            "    @Provides A provideA2(String s) { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module(includes = { Module1.class, Module2.class})",
-            "  abstract static class Module3 {}",
-            "",
-            "  @Component(modules = { Module1.class, Module2.class})",
-            "  interface TestComponent {",
-            "    A getA();",
-            "    B getB();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Outer.A is bound multiple times:",
-                "    @Provides test.Outer.A test.Outer.Module1.provideA1()",
-                "    @Provides test.Outer.A test.Outer.Module2.provideA2(String)"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-
-    if (fullBindingGraphValidation) {
-      assertThat(compilation)
-          .hadErrorContaining(
-              message(
-                  "test.Outer.A is bound multiple times:",
-                  "    @Provides test.Outer.A test.Outer.Module1.provideA1()",
-                  "    @Provides test.Outer.A test.Outer.Module2.provideA2(String)"))
-          .inFile(component)
-          .onLineContaining("class Module3");
-    }
-
-    // The duplicate bindngs are also requested from B, but we don't want to report them again.
-    assertThat(compilation).hadErrorCount(fullBindingGraphValidation ? 2 : 1);
-  }
-
-  @Test
-  public void duplicateExplicitBindings_ProvidesVsBinds() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  interface A {}",
-            "",
-            "  static final class B implements A {",
-            "    @Inject B() {}",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module1 {",
-            "    @Provides A provideA1() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static abstract class Module2 {",
-            "    @Binds abstract A bindA2(B b);",
-            "  }",
-            "",
-            "  @Module(includes = { Module1.class, Module2.class})",
-            "  abstract static class Module3 {}",
-            "",
-            "  @Component(modules = { Module1.class, Module2.class})",
-            "  interface TestComponent {",
-            "    A getA();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Outer.A is bound multiple times:",
-                "    @Provides test.Outer.A test.Outer.Module1.provideA1()",
-                "    @Binds test.Outer.A test.Outer.Module2.bindA2(test.Outer.B)"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-
-    if (fullBindingGraphValidation) {
-      assertThat(compilation)
-          .hadErrorContaining(
-              message(
-                  "test.Outer.A is bound multiple times:",
-                  "    @Provides test.Outer.A test.Outer.Module1.provideA1()",
-                  "    @Binds test.Outer.A test.Outer.Module2.bindA2(test.Outer.B)"))
-          .inFile(component)
-          .onLineContaining("class Module3");
-    }
-  }
-
-  @Test
-  public void duplicateExplicitBindings_multibindingsAndExplicitSets() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.HashSet;",
-            "import java.util.Set;",
-            "import javax.inject.Qualifier;",
-            "",
-            "final class Outer {",
-            "  @Qualifier @interface SomeQualifier {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule1 {",
-            "    @Provides @IntoSet static String stringSetElement() { return \"\"; }",
-            "",
-            "    @Binds",
-            "    @IntoSet abstract String bindStringSetElement(@SomeQualifier String value);",
-            "",
-            "    @Provides @SomeQualifier",
-            "    static String provideSomeQualifiedString() { return \"\"; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class TestModule2 {",
-            "    @Provides Set<String> stringSet() { return new HashSet<String>(); }",
-            "  }",
-            "",
-            "  @Module(includes = { TestModule1.class, TestModule2.class})",
-            "  abstract static class TestModule3 {}",
-            "",
-            "  @Component(modules = { TestModule1.class, TestModule2.class })",
-            "  interface TestComponent {",
-            "    Set<String> getStringSet();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.Set<java.lang.String> has incompatible bindings or declarations:",
-                "    Set bindings and declarations:",
-                "        @Binds @dagger.multibindings.IntoSet String "
-                    + "test.Outer.TestModule1.bindStringSetElement(@test.Outer.SomeQualifier "
-                    + "String)",
-                "        @Provides @dagger.multibindings.IntoSet String "
-                    + "test.Outer.TestModule1.stringSetElement()",
-                "    Unique bindings and declarations:",
-                "        @Provides Set<String> test.Outer.TestModule2.stringSet()"))
-        .inFile(component)
-        .onLineContaining(
-            fullBindingGraphValidation ? "class TestModule3" : "interface TestComponent");
-  }
-
-  @Test
-  public void duplicateExplicitBindings_multibindingsAndExplicitMaps() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.HashMap;",
-            "import java.util.Map;",
-            "import javax.inject.Qualifier;",
-            "",
-            "final class Outer {",
-            "  @Qualifier @interface SomeQualifier {}",
-            "",
-            "  @Module",
-            "  abstract static class TestModule1 {",
-            "    @Provides @IntoMap",
-            "    @StringKey(\"foo\")",
-            "    static String stringMapEntry() { return \"\"; }",
-            "",
-            "    @Binds @IntoMap @StringKey(\"bar\")",
-            "    abstract String bindStringMapEntry(@SomeQualifier String value);",
-            "",
-            "    @Provides @SomeQualifier",
-            "    static String provideSomeQualifiedString() { return \"\"; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class TestModule2 {",
-            "    @Provides Map<String, String> stringMap() {",
-            "      return new HashMap<String, String>();",
-            "    }",
-            "  }",
-            "",
-            "  @Module(includes = { TestModule1.class, TestModule2.class})",
-            "  abstract static class TestModule3 {}",
-            "",
-            "  @Component(modules = { TestModule1.class, TestModule2.class })",
-            "  interface TestComponent {",
-            "    Map<String, String> getStringMap();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.Map<java.lang.String,java.lang.String> has incompatible bindings "
-                    + "or declarations:",
-                "    Map bindings and declarations:",
-                "        @Binds @dagger.multibindings.IntoMap "
-                    + "@dagger.multibindings.StringKey(\"bar\") String"
-                    + " test.Outer.TestModule1.bindStringMapEntry(@test.Outer.SomeQualifier "
-                    + "String)",
-                "        @Provides @dagger.multibindings.IntoMap "
-                    + "@dagger.multibindings.StringKey(\"foo\") String"
-                    + " test.Outer.TestModule1.stringMapEntry()",
-                "    Unique bindings and declarations:",
-                "        @Provides Map<String,String> test.Outer.TestModule2.stringMap()"))
-        .inFile(component)
-        .onLineContaining(
-            fullBindingGraphValidation ? "class TestModule3" : "interface TestComponent");
-  }
-
-  @Test
-  public void duplicateExplicitBindings_UniqueBindingAndMultibindingDeclaration_Set() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.HashSet;",
-            "import java.util.Set;",
-            "",
-            "final class Outer {",
-            "  @Module",
-            "  abstract static class TestModule1 {",
-            "    @Multibinds abstract Set<String> stringSet();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class TestModule2 {",
-            "    @Provides Set<String> stringSet() { return new HashSet<String>(); }",
-            "  }",
-            "",
-            "  @Module(includes = { TestModule1.class, TestModule2.class})",
-            "  abstract static class TestModule3 {}",
-            "",
-            "  @Component(modules = { TestModule1.class, TestModule2.class })",
-            "  interface TestComponent {",
-            "    Set<String> getStringSet();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.Set<java.lang.String> has incompatible bindings or declarations:",
-                "    Set bindings and declarations:",
-                "        @dagger.multibindings.Multibinds Set<String> "
-                    + "test.Outer.TestModule1.stringSet()",
-                "    Unique bindings and declarations:",
-                "        @Provides Set<String> test.Outer.TestModule2.stringSet()"))
-        .inFile(component)
-        .onLineContaining(
-            fullBindingGraphValidation ? "class TestModule3" : "interface TestComponent");
-  }
-
-  @Test
-  public void duplicateExplicitBindings_UniqueBindingAndMultibindingDeclaration_Map() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.HashMap;",
-            "import java.util.Map;",
-            "",
-            "final class Outer {",
-            "  @Module",
-            "  abstract static class TestModule1 {",
-            "    @Multibinds abstract Map<String, String> stringMap();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class TestModule2 {",
-            "    @Provides Map<String, String> stringMap() {",
-            "      return new HashMap<String, String>();",
-            "    }",
-            "  }",
-            "",
-            "  @Module(includes = { TestModule1.class, TestModule2.class})",
-            "  abstract static class TestModule3 {}",
-            "",
-            "  @Component(modules = { TestModule1.class, TestModule2.class })",
-            "  interface TestComponent {",
-            "    Map<String, String> getStringMap();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.Map<java.lang.String,java.lang.String> has incompatible bindings "
-                    + "or declarations:",
-                "    Map bindings and declarations:",
-                "        @dagger.multibindings.Multibinds Map<String,String> "
-                    + "test.Outer.TestModule1.stringMap()",
-                "    Unique bindings and declarations:",
-                "        @Provides Map<String,String> test.Outer.TestModule2.stringMap()"))
-        .inFile(component)
-        .onLineContaining(
-            fullBindingGraphValidation ? "class TestModule3" : "interface TestComponent");
-  }
-
-  @Test public void duplicateBindings_TruncateAfterLimit() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Outer",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Outer {",
-            "  interface A {}",
-            "",
-            "  @Module",
-            "  static class Module01 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module02 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module03 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module04 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module05 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module06 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module07 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module08 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module09 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module10 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module11 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module",
-            "  static class Module12 {",
-            "    @Provides A provideA() { return new A() {}; }",
-            "  }",
-            "",
-            "  @Module(includes = {",
-            "    Module01.class,",
-            "    Module02.class,",
-            "    Module03.class,",
-            "    Module04.class,",
-            "    Module05.class,",
-            "    Module06.class,",
-            "    Module07.class,",
-            "    Module08.class,",
-            "    Module09.class,",
-            "    Module10.class,",
-            "    Module11.class,",
-            "    Module12.class",
-            "  })",
-            "  abstract static class Modules {}",
-            "",
-            "  @Component(modules = {",
-            "    Module01.class,",
-            "    Module02.class,",
-            "    Module03.class,",
-            "    Module04.class,",
-            "    Module05.class,",
-            "    Module06.class,",
-            "    Module07.class,",
-            "    Module08.class,",
-            "    Module09.class,",
-            "    Module10.class,",
-            "    Module11.class,",
-            "    Module12.class",
-            "  })",
-            "  interface TestComponent {",
-            "    A getA();",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(fullBindingGraphValidationOption()).compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Outer.A is bound multiple times:",
-                "    @Provides test.Outer.A test.Outer.Module01.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module02.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module03.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module04.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module05.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module06.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module07.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module08.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module09.provideA()",
-                "    @Provides test.Outer.A test.Outer.Module10.provideA()",
-                "    and 2 others"))
-        .inFile(component)
-        .onLineContaining(fullBindingGraphValidation ? "class Modules" : "interface TestComponent");
-  }
-
-  @Test
-  public void childBindingConflictsWithParent() {
-    JavaFileObject aComponent =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Component(modules = A.AModule.class)",
-            "interface A {",
-            "  Object conflict();",
-            "",
-            "  B.Builder b();",
-            "",
-            "  @Module(subcomponents = B.class)",
-            "  static class AModule {",
-            "    @Provides static Object abConflict() {",
-            "      return \"a\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject bComponent =
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = B.BModule.class)",
-            "interface B {",
-            "  Object conflict();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    B build();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class BModule {",
-            "    @Provides static Object abConflict() {",
-            "      return \"b\";",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(fullBindingGraphValidationOption())
-            .compile(aComponent, bComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.Object is bound multiple times:",
-                "    @Provides Object test.A.AModule.abConflict()",
-                "    @Provides Object test.B.BModule.abConflict()"))
-        .inFile(aComponent)
-        .onLineContaining(fullBindingGraphValidation ? "class AModule" : "interface A {");
-  }
-
-  @Test
-  public void grandchildBindingConflictsWithGrandparent() {
-    JavaFileObject aComponent =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Component(modules = A.AModule.class)",
-            "interface A {",
-            "  Object conflict();",
-            "",
-            "  B.Builder b();",
-            "",
-            "  @Module(subcomponents = B.class)",
-            "  static class AModule {",
-            "    @Provides static Object acConflict() {",
-            "      return \"a\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject bComponent =
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface B {",
-            "  C.Builder c();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    B build();",
-            "  }",
-            "}");
-    JavaFileObject cComponent =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = C.CModule.class)",
-            "interface C {",
-            "  Object conflict();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    C build();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class CModule {",
-            "    @Provides static Object acConflict() {",
-            "      return \"c\";",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(fullBindingGraphValidationOption())
-            .compile(aComponent, bComponent, cComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.Object is bound multiple times:",
-                "    @Provides Object test.A.AModule.acConflict()",
-                "    @Provides Object test.C.CModule.acConflict()"))
-        .inFile(aComponent)
-        .onLineContaining(fullBindingGraphValidation ? "class AModule" : "interface A {");
-  }
-
-  @Test
-  public void grandchildBindingConflictsWithChild() {
-    JavaFileObject aComponent =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface A {",
-            "  B b();",
-            "}");
-    JavaFileObject bComponent =
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = B.BModule.class)",
-            "interface B {",
-            "  Object conflict();",
-            "",
-            "  C.Builder c();",
-            "",
-            "  @Module(subcomponents = C.class)",
-            "  static class BModule {",
-            "    @Provides static Object bcConflict() {",
-            "      return \"b\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject cComponent =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = C.CModule.class)",
-            "interface C {",
-            "  Object conflict();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    C build();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class CModule {",
-            "    @Provides static Object bcConflict() {",
-            "      return \"c\";",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(fullBindingGraphValidationOption())
-            .compile(aComponent, bComponent, cComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.Object is bound multiple times:",
-                "    @Provides Object test.B.BModule.bcConflict()",
-                "    @Provides Object test.C.CModule.bcConflict()"))
-        .inFile(fullBindingGraphValidation ? bComponent : aComponent)
-        .onLineContaining(fullBindingGraphValidation ? "class BModule" : "interface A {");
-  }
-
-  @Test
-  public void childProvidesConflictsWithParentInjects() {
-    assumeFalse(fullBindingGraphValidation);
-
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import java.util.Set;",
-            "import javax.inject.Inject;",
-            "",
-            "final class Foo {",
-            "  @Inject Foo(Set<String> strings) {}",
-            "}");
-    JavaFileObject injected1 =
-        JavaFileObjects.forSourceLines(
-            "test.Injected1",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Component(modules = Injected1.Injected1Module.class)",
-            "interface Injected1 {",
-            "  Foo foo();",
-            "  Injected2 injected2();",
-            "",
-            "  @Module",
-            "  interface Injected1Module {",
-            "    @Provides @IntoSet static String string() {",
-            "      return \"injected1\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject injected2 =
-        JavaFileObjects.forSourceLines(
-            "test.Injected2",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = Injected2.Injected2Module.class)",
-            "interface Injected2 {",
-            "  Foo foo();",
-            "  Provided1 provided1();",
-            "",
-            "  @Module",
-            "  interface Injected2Module {",
-            "    @Provides @IntoSet static String string() {",
-            "      return \"injected2\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject provided1 =
-        JavaFileObjects.forSourceLines(
-            "test.Provided1",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = Provided1.Provided1Module.class)",
-            "interface Provided1 {",
-            "  Foo foo();",
-            "  Provided2 provided2();",
-            "",
-            "  @Module",
-            "  static class Provided1Module {",
-            "    @Provides static Foo provideFoo(Set<String> strings) {",
-            "      return new Foo(strings);",
-            "    }",
-            "",
-            "    @Provides @IntoSet static String string() {",
-            "      return \"provided1\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject provided2 =
-        JavaFileObjects.forSourceLines(
-            "test.Provided2",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Subcomponent(modules = Provided2.Provided2Module.class)",
-            "interface Provided2 {",
-            "  Foo foo();",
-            "",
-            "  @Module",
-            "  static class Provided2Module {",
-            "    @Provides @IntoSet static String string() {",
-            "      return \"provided2\";",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(foo, injected1, injected2, provided1, provided2);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining(
-            message(
-                "test.Foo is bound multiple times:",
-                "    @Inject test.Foo(Set<String>) [test.Injected1]",
-                "    @Provides test.Foo test.Provided1.Provided1Module.provideFoo(Set<String>) "
-                    + "[test.Injected1 → test.Injected2 → test.Provided1]"))
-        .inFile(injected1)
-        .onLineContaining("interface Injected1 {");
-  }
-
-  @Test
-  public void grandchildBindingConflictsWithParentWithNullableViolationAsWarning() {
-    JavaFileObject parentConflictsWithChild =
-        JavaFileObjects.forSourceLines(
-            "test.ParentConflictsWithChild",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.annotation.Nullable;",
-            "",
-            "@Component(modules = ParentConflictsWithChild.ParentModule.class)",
-            "interface ParentConflictsWithChild {",
-            "  Child.Builder child();",
-            "",
-            "  @Module(subcomponents = Child.class)",
-            "  static class ParentModule {",
-            "    @Provides @Nullable static Object nullableParentChildConflict() {",
-            "      return \"parent\";",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = Child.ChildModule.class)",
-            "interface Child {",
-            "  Object parentChildConflictThatViolatesNullability();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "",
-            "  @Module",
-            "  static class ChildModule {",
-            "    @Provides static Object nonNullableParentChildConflict() {",
-            "      return \"child\";",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.nullableValidation=WARNING", fullBindingGraphValidationOption())
-            .compile(parentConflictsWithChild, child);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.Object is bound multiple times:",
-                "    @Provides Object test.Child.ChildModule.nonNullableParentChildConflict()",
-                "    @Provides @javax.annotation.Nullable Object"
-                    + " test.ParentConflictsWithChild.ParentModule.nullableParentChildConflict()"))
-        .inFile(parentConflictsWithChild)
-        .onLineContaining(
-            fullBindingGraphValidation
-                ? "class ParentModule"
-                : "interface ParentConflictsWithChild");
-  }
-
-  private String fullBindingGraphValidationOption() {
-    return "-Adagger.fullBindingGraphValidation=" + (fullBindingGraphValidation ? "ERROR" : "NONE");
-  }
-
-  @Test
-  public void reportedInParentAndChild() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child.Builder childBuilder();",
-            "  String duplicated();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.Optional;",
-            "",
-            "@Module",
-            "interface ParentModule {",
-            "  @Provides static String one(Optional<Object> optional) { return \"one\"; }",
-            "  @Provides static String two() { return \"two\"; }",
-            "  @BindsOptionalOf Object optional();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  String duplicated();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.Optional;",
-            "",
-            "@Module",
-            "interface ChildModule {",
-            "  @Provides static Object object() { return \"object\"; }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(parent, parentModule, child, childModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("java.lang.String is bound multiple times")
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-    assertThat(compilation).hadErrorCount(1);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ElidedFactoriesTest.java b/javatests/dagger/internal/codegen/ElidedFactoriesTest.java
deleted file mode 100644
index 58ddb82..0000000
--- a/javatests/dagger/internal/codegen/ElidedFactoriesTest.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ElidedFactoriesTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ElidedFactoriesTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void simpleComponent() {
-    JavaFileObject injectedType =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class InjectedType {",
-            "  @Inject InjectedType() {}",
-            "}");
-
-    JavaFileObject dependsOnInjected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class DependsOnInjected {",
-            "  @Inject DependsOnInjected(InjectedType injected) {}",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface SimpleComponent {",
-            "  DependsOnInjected dependsOnInjected();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerSimpleComponent",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerSimpleComponent implements SimpleComponent {",
-            "  private DaggerSimpleComponent() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static SimpleComponent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public DependsOnInjected dependsOnInjected() {",
-            "    return new DependsOnInjected(new InjectedType());",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {",
-            "    }",
-            "",
-            "    public SimpleComponent build() {",
-            "      return new DaggerSimpleComponent();",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(injectedType, dependsOnInjected, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test
-  public void simpleComponent_injectsProviderOf_dependsOnScoped() {
-    JavaFileObject scopedType =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "final class ScopedType {",
-            "  @Inject ScopedType() {}",
-            "}");
-
-    JavaFileObject dependsOnScoped =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class DependsOnScoped {",
-            "  @Inject DependsOnScoped(ScopedType scoped) {}",
-            "}");
-
-    JavaFileObject needsProvider =
-        JavaFileObjects.forSourceLines(
-            "test.NeedsProvider",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "class NeedsProvider {",
-            "  @Inject NeedsProvider(Provider<DependsOnScoped> provider) {}",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface SimpleComponent {",
-            "  NeedsProvider needsProvider();",
-            "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerSimpleComponent",
-                "package test;",
-                "",
-                "import dagger.internal.DoubleCheck;",
-                "import dagger.internal.MemoizedSentinel;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private volatile Object scopedType = new MemoizedSentinel();",
-                "  private volatile Provider<DependsOnScoped> dependsOnScopedProvider;",
-                "",
-                "  private DaggerSimpleComponent() {}",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  private ScopedType getScopedType() {",
-                "    Object local = scopedType;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = scopedType;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = new ScopedType();",
-                "          scopedType = DoubleCheck.reentrantCheck(scopedType, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (ScopedType) local;",
-                "  }",
-                "",
-                "  private DependsOnScoped getDependsOnScoped() {",
-                "    return new DependsOnScoped(getScopedType());",
-                "  }",
-                "",
-                "  private Provider<DependsOnScoped> getDependsOnScopedProvider() {",
-                "    Object local = dependsOnScopedProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      dependsOnScopedProvider = (Provider<DependsOnScoped>) local;",
-                "    }",
-                "    return (Provider<DependsOnScoped>) local;",
-                "  }",
-                "",
-                "  @Override",
-                "  public NeedsProvider needsProvider() {",
-                "    return new NeedsProvider(getDependsOnScopedProvider());",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private Builder() {}",
-                "",
-                "    public SimpleComponent build() {",
-                "      return new DaggerSimpleComponent();",
-                "    }",
-                "  }",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) DaggerSimpleComponent.this.getDependsOnScoped();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerSimpleComponent",
-                "package test;",
-                "",
-                "import dagger.internal.DoubleCheck;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private Provider<ScopedType> scopedTypeProvider;",
-                "  private Provider<DependsOnScoped> dependsOnScopedProvider;",
-                "",
-                "  private DaggerSimpleComponent() {",
-                "    initialize();",
-                "  }",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.scopedTypeProvider = DoubleCheck.provider(ScopedType_Factory.create());",
-                "    this.dependsOnScopedProvider = ",
-                "        DependsOnScoped_Factory.create(scopedTypeProvider);",
-                "  }",
-                "",
-                "  @Override",
-                "  public NeedsProvider needsProvider() {",
-                "    return new NeedsProvider(dependsOnScopedProvider);",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private Builder() {",
-                "    }",
-                "",
-                "    public SimpleComponent build() {",
-                "      return new DaggerSimpleComponent();",
-                "    }",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(scopedType, dependsOnScoped, componentFile, needsProvider);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  @Test
-  public void scopedBinding_onlyUsedInSubcomponent() {
-    JavaFileObject scopedType =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "final class ScopedType {",
-            "  @Inject ScopedType() {}",
-            "}");
-
-    JavaFileObject dependsOnScoped =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class DependsOnScoped {",
-            "  @Inject DependsOnScoped(ScopedType scoped) {}",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface SimpleComponent {",
-            "  Sub sub();",
-            "}");
-    JavaFileObject subcomponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  DependsOnScoped dependsOnScoped();",
-            "}");
-
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerSimpleComponent",
-                "package test;",
-                "",
-                "import dagger.internal.DoubleCheck;",
-                "import dagger.internal.MemoizedSentinel;",
-                IMPORT_GENERATED_ANNOTATION,
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private volatile Object scopedType = new MemoizedSentinel();",
-                "",
-                "  private DaggerSimpleComponent() {}",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  private ScopedType getScopedType() {",
-                "    Object local = scopedType;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = scopedType;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = new ScopedType();",
-                "          scopedType = DoubleCheck.reentrantCheck(scopedType, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (ScopedType) local;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Sub sub() {",
-                "    return new SubImpl();",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private Builder() {}",
-                "",
-                "    public SimpleComponent build() {",
-                "      return new DaggerSimpleComponent();",
-                "    }",
-                "  }",
-                "",
-                "  private final class SubImpl implements Sub {",
-                "    private SubImpl() {}",
-                "",
-                "    @Override",
-                "    public DependsOnScoped dependsOnScoped() {",
-                "      return new DependsOnScoped(DaggerSimpleComponent.this.getScopedType());",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerSimpleComponent",
-                "package test;",
-                "",
-                "import dagger.internal.DoubleCheck;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerSimpleComponent implements SimpleComponent {",
-                "  private Provider<ScopedType> scopedTypeProvider;",
-                "",
-                "  private DaggerSimpleComponent() {",
-                "    initialize();",
-                "  }",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.scopedTypeProvider = DoubleCheck.provider(ScopedType_Factory.create());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Sub sub() {",
-                "    return new SubImpl();",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private Builder() {}",
-                "",
-                "    public SimpleComponent build() {",
-                "      return new DaggerSimpleComponent();",
-                "    }",
-                "  }",
-                "",
-                "  private final class SubImpl implements Sub {",
-                "    private SubImpl() {}",
-                "",
-                "    @Override",
-                "    public DependsOnScoped dependsOnScoped() {",
-                "      return new DependsOnScoped(",
-                "          DaggerSimpleComponent.this.scopedTypeProvider.get());",
-                "    }",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(scopedType, dependsOnScoped, componentFile, subcomponentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerSimpleComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/FrameworkFieldTest.java b/javatests/dagger/internal/codegen/FrameworkFieldTest.java
deleted file mode 100644
index cbc8c03..0000000
--- a/javatests/dagger/internal/codegen/FrameworkFieldTest.java
+++ /dev/null
@@ -1,65 +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.truth.Truth.assertThat;
-import static dagger.internal.codegen.javapoet.TypeNames.MEMBERS_INJECTOR;
-import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER;
-import static dagger.internal.codegen.javapoet.TypeNames.membersInjectorOf;
-import static dagger.internal.codegen.javapoet.TypeNames.providerOf;
-
-import com.google.testing.compile.CompilationRule;
-import com.squareup.javapoet.ClassName;
-import javax.inject.Inject;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Test case for {@link FrameworkField}.
- */
-@RunWith(JUnit4.class)
-public class FrameworkFieldTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-
-  private ClassName xTypeName;
-
-  @Before public void setUp() {
-    xTypeName =
-        ClassName.get(compilationRule.getElements().getTypeElement(X.class.getCanonicalName()));
-  }
-
-  @Test public void frameworkType() {
-    assertThat(FrameworkField.create(PROVIDER, xTypeName, "test").type())
-        .isEqualTo(providerOf(xTypeName));
-    assertThat(FrameworkField.create(MEMBERS_INJECTOR, xTypeName, "test").type())
-        .isEqualTo(membersInjectorOf(xTypeName));
-  }
-
-  @Test public void nameSuffix() {
-    assertThat(FrameworkField.create(PROVIDER, xTypeName, "foo").name())
-        .isEqualTo("fooProvider");
-    assertThat(FrameworkField.create(PROVIDER, xTypeName, "fooProvider").name())
-        .isEqualTo("fooProvider");
-  }
-
-  static final class X {
-    @Inject X() {}
-  }
-}
diff --git a/javatests/dagger/internal/codegen/FrameworkTypeMapperTest.java b/javatests/dagger/internal/codegen/FrameworkTypeMapperTest.java
deleted file mode 100644
index 3e6e3ad..0000000
--- a/javatests/dagger/internal/codegen/FrameworkTypeMapperTest.java
+++ /dev/null
@@ -1,48 +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.truth.Truth.assertThat;
-import static dagger.model.RequestKind.INSTANCE;
-import static dagger.model.RequestKind.LAZY;
-import static dagger.model.RequestKind.PRODUCED;
-import static dagger.model.RequestKind.PRODUCER;
-import static dagger.model.RequestKind.PROVIDER;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Test case for {@link FrameworkTypeMapper}. */
-@RunWith(JUnit4.class)
-public class FrameworkTypeMapperTest {
-  @Test public void forProvider() {
-    FrameworkTypeMapper mapper = FrameworkTypeMapper.FOR_PROVIDER;
-    assertThat(mapper.getFrameworkType(INSTANCE)).isEqualTo(FrameworkType.PROVIDER);
-    assertThat(mapper.getFrameworkType(LAZY)).isEqualTo(FrameworkType.PROVIDER);
-    assertThat(mapper.getFrameworkType(PROVIDER)).isEqualTo(FrameworkType.PROVIDER);
-  }
-
-  @Test public void forProducer() {
-    FrameworkTypeMapper mapper = FrameworkTypeMapper.FOR_PRODUCER;
-    assertThat(mapper.getFrameworkType(INSTANCE)).isEqualTo(FrameworkType.PRODUCER_NODE);
-    assertThat(mapper.getFrameworkType(LAZY)).isEqualTo(FrameworkType.PROVIDER);
-    assertThat(mapper.getFrameworkType(PROVIDER)).isEqualTo(FrameworkType.PROVIDER);
-    assertThat(mapper.getFrameworkType(PRODUCER)).isEqualTo(FrameworkType.PRODUCER_NODE);
-    assertThat(mapper.getFrameworkType(PRODUCED)).isEqualTo(FrameworkType.PRODUCER_NODE);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/FullBindingGraphValidationTest.java b/javatests/dagger/internal/codegen/FullBindingGraphValidationTest.java
deleted file mode 100644
index 944e307..0000000
--- a/javatests/dagger/internal/codegen/FullBindingGraphValidationTest.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.endsWithMessage;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.regex.Pattern;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class FullBindingGraphValidationTest {
-  private static final JavaFileObject MODULE_WITH_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.ModuleWithErrors",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module",
-          "interface ModuleWithErrors {",
-          "  @Binds Object object1(String string);",
-          "  @Binds Object object2(Long l);",
-          "  @Binds Number missingDependency(Integer i);",
-          "}");
-
-  // Make sure the error doesn't show other bindings or a dependency trace afterwards.
-  private static final Pattern MODULE_WITH_ERRORS_MESSAGE =
-      endsWithMessage(
-          "[Dagger/DuplicateBindings] java.lang.Object is bound multiple times:",
-          "    @Binds Object test.ModuleWithErrors.object1(String)",
-          "    @Binds Object test.ModuleWithErrors.object2(Long)");
-
-  @Test
-  public void moduleWithErrors_validationTypeNone() {
-    Compilation compilation = daggerCompiler().compile(MODULE_WITH_ERRORS);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void moduleWithErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(MODULE_WITH_ERRORS);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(MODULE_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithErrors");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void moduleWithErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(MODULE_WITH_ERRORS);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(MODULE_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithErrors");
-
-    assertThat(compilation).hadWarningCount(1);
-  }
-
-  private static final JavaFileObject INCLUDES_MODULE_WITH_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.IncludesModuleWithErrors",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module(includes = ModuleWithErrors.class)",
-          "interface IncludesModuleWithErrors {}");
-
-  @Test
-  public void includesModuleWithErrors_validationTypeNone() {
-    Compilation compilation =
-        daggerCompiler().compile(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void includesModuleWithErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(MODULE_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithErrors");
-
-    assertThat(compilation)
-        .hadErrorContainingMatch("test.ModuleWithErrors has errors")
-        .inFile(INCLUDES_MODULE_WITH_ERRORS)
-        .onLineContaining("ModuleWithErrors.class");
-
-    assertThat(compilation).hadErrorCount(2);
-  }
-
-  @Test
-  public void includesModuleWithErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(MODULE_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithErrors");
-
-    // TODO(b/130284666)
-    assertThat(compilation)
-        .hadWarningContainingMatch(MODULE_WITH_ERRORS_MESSAGE)
-        .inFile(INCLUDES_MODULE_WITH_ERRORS)
-        .onLineContaining("interface IncludesModuleWithErrors");
-
-    assertThat(compilation).hadWarningCount(2);
-  }
-
-  private static final JavaFileObject A_MODULE =
-      JavaFileObjects.forSourceLines(
-          "test.AModule",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module",
-          "interface AModule {",
-          "  @Binds Object object(String string);",
-          "}");
-
-  private static final JavaFileObject COMBINED_WITH_A_MODULE_HAS_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.CombinedWithAModuleHasErrors",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module(includes = AModule.class)",
-          "interface CombinedWithAModuleHasErrors {",
-          "  @Binds Object object(Long l);",
-          "}");
-
-  // Make sure the error doesn't show other bindings or a dependency trace afterwards.
-  private static final Pattern COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE =
-      endsWithMessage(
-          "[Dagger/DuplicateBindings] java.lang.Object is bound multiple times:",
-          "    @Binds Object test.AModule.object(String)",
-          "    @Binds Object test.CombinedWithAModuleHasErrors.object(Long)");
-
-  @Test
-  public void moduleIncludingModuleWithCombinedErrors_validationTypeNone() {
-    Compilation compilation = daggerCompiler().compile(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS);
-
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void moduleIncludingModuleWithCombinedErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE)
-        .inFile(COMBINED_WITH_A_MODULE_HAS_ERRORS)
-        .onLineContaining("interface CombinedWithAModuleHasErrors");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void moduleIncludingModuleWithCombinedErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE)
-        .inFile(COMBINED_WITH_A_MODULE_HAS_ERRORS)
-        .onLineContaining("interface CombinedWithAModuleHasErrors");
-
-    assertThat(compilation).hadWarningCount(1);
-  }
-
-  private static final JavaFileObject SUBCOMPONENT_WITH_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.SubcomponentWithErrors",
-          "package test;",
-          "",
-          "import dagger.BindsInstance;",
-          "import dagger.Subcomponent;",
-          "",
-          "@Subcomponent(modules = AModule.class)",
-          "interface SubcomponentWithErrors {",
-          "  @Subcomponent.Builder",
-          "  interface Builder {",
-          "    @BindsInstance Builder object(Object object);",
-          "    SubcomponentWithErrors build();",
-          "  }",
-          "}");
-
-  // Make sure the error doesn't show other bindings or a dependency trace afterwards.
-  private static final Pattern SUBCOMPONENT_WITH_ERRORS_MESSAGE =
-      endsWithMessage(
-          "[Dagger/DuplicateBindings] java.lang.Object is bound multiple times:",
-          "    @Binds Object test.AModule.object(String)",
-          "    @BindsInstance test.SubcomponentWithErrors.Builder"
-              + " test.SubcomponentWithErrors.Builder.object(Object)");
-
-  @Test
-  public void subcomponentWithErrors_validationTypeNone() {
-    Compilation compilation = daggerCompiler().compile(SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void subcomponentWithErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface SubcomponentWithErrors");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void subcomponentWithErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface SubcomponentWithErrors");
-
-    assertThat(compilation).hadWarningCount(1);
-  }
-
-  private static final JavaFileObject MODULE_WITH_SUBCOMPONENT_WITH_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.ModuleWithSubcomponentWithErrors",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module(subcomponents = SubcomponentWithErrors.class)",
-          "interface ModuleWithSubcomponentWithErrors {}");
-
-  @Test
-  public void moduleWithSubcomponentWithErrors_validationTypeNone() {
-    Compilation compilation =
-        daggerCompiler()
-            .compile(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void moduleWithSubcomponentWithErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithSubcomponentWithErrors");
-
-    // TODO(b/130283677)
-    assertThat(compilation)
-        .hadErrorContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface SubcomponentWithErrors");
-
-    assertThat(compilation).hadErrorCount(2);
-  }
-
-  @Test
-  public void moduleWithSubcomponentWithErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface ModuleWithSubcomponentWithErrors");
-
-    // TODO(b/130283677)
-    assertThat(compilation)
-        .hadWarningContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE)
-        .inFile(SUBCOMPONENT_WITH_ERRORS)
-        .onLineContaining("interface SubcomponentWithErrors");
-
-    assertThat(compilation).hadWarningCount(2);
-  }
-
-  private static final JavaFileObject A_SUBCOMPONENT =
-      JavaFileObjects.forSourceLines(
-          "test.ASubcomponent",
-          "package test;",
-          "",
-          "import dagger.BindsInstance;",
-          "import dagger.Subcomponent;",
-          "",
-          "@Subcomponent(modules = AModule.class)",
-          "interface ASubcomponent {",
-          "  @Subcomponent.Builder",
-          "  interface Builder {",
-          "    ASubcomponent build();",
-          "  }",
-          "}");
-
-  private static final JavaFileObject COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS =
-      JavaFileObjects.forSourceLines(
-          "test.CombinedWithASubcomponentHasErrors",
-          "package test;",
-          "",
-          "import dagger.Binds;",
-          "import dagger.Module;",
-          "",
-          "@Module(subcomponents = ASubcomponent.class)",
-          "interface CombinedWithASubcomponentHasErrors {",
-          "  @Binds Object object(Number number);",
-          "}");
-
-  // Make sure the error doesn't show other bindings or a dependency trace afterwards.
-  private static final Pattern COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE =
-      endsWithMessage(
-          "[Dagger/DuplicateBindings] java.lang.Object is bound multiple times:",
-          "    @Binds Object test.AModule.object(String)",
-          "    @Binds Object test.CombinedWithASubcomponentHasErrors.object(Number)");
-
-  @Test
-  public void moduleWithSubcomponentWithCombinedErrors_validationTypeNone() {
-    Compilation compilation =
-        daggerCompiler().compile(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE);
-
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void moduleWithSubcomponentWithCombinedErrors_validationTypeError() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContainingMatch(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE)
-        .inFile(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS)
-        .onLineContaining("interface CombinedWithASubcomponentHasErrors");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void moduleWithSubcomponentWithCombinedErrors_validationTypeWarning() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=WARNING")
-            .compile(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContainingMatch(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE)
-        .inFile(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS)
-        .onLineContaining("interface CombinedWithASubcomponentHasErrors");
-
-    assertThat(compilation).hadWarningCount(1);
-  }
-
-  @Test
-  public void bothAliasesDifferentValues() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                "-Adagger.moduleBindingValidation=NONE",
-                "-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(MODULE_WITH_ERRORS);
-
-    assertThat(compilation).failed();
-
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Only one of the equivalent options "
-                + "(-Adagger.fullBindingGraphValidation, -Adagger.moduleBindingValidation)"
-                + " should be used; prefer -Adagger.fullBindingGraphValidation");
-
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void bothAliasesSameValue() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                "-Adagger.moduleBindingValidation=NONE", "-Adagger.fullBindingGraphValidation=NONE")
-            .compile(MODULE_WITH_ERRORS);
-
-    assertThat(compilation).succeeded();
-
-    assertThat(compilation)
-        .hadWarningContaining(
-            "Only one of the equivalent options "
-                + "(-Adagger.fullBindingGraphValidation, -Adagger.moduleBindingValidation)"
-                + " should be used; prefer -Adagger.fullBindingGraphValidation");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/GeneratedLines.java b/javatests/dagger/internal/codegen/GeneratedLines.java
deleted file mode 100644
index 2aa17ac..0000000
--- a/javatests/dagger/internal/codegen/GeneratedLines.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2015 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 dagger.internal.codegen.javapoet.CodeBlocks.stringLiteral;
-
-import com.squareup.javapoet.CodeBlock;
-
-/**
- * Common lines outputted during code generation.
- */
-public final class GeneratedLines {
-  public static final String GENERATED_ANNOTATION =
-     "@Generated("
-        + "value = \"dagger.internal.codegen.ComponentProcessor\", "
-        + "comments = \"https://dagger.dev\")";
-
-  public static final String IMPORT_GENERATED_ANNOTATION =
-      isBeforeJava9()
-          ? "import javax.annotation.Generated;"
-          : "import javax.annotation.processing.Generated;";
-
-  static final String GENERATION_OPTIONS_ANNOTATION = "@GenerationOptions(fastInit = false)";
-
-  private static boolean isBeforeJava9() {
-    try {
-      Class.forName("java.lang.Module");
-      return false;
-    } catch (ClassNotFoundException e) {
-      return true;
-    }
-  }
-
-  public static final CodeBlock NPE_FROM_PROVIDES_METHOD =
-      stringLiteral("Cannot return null from a non-@Nullable @Provides method");
-
-  public static final CodeBlock NPE_FROM_COMPONENT_METHOD =
-      stringLiteral("Cannot return null from a non-@Nullable component method");
-}
diff --git a/javatests/dagger/internal/codegen/GeneratingProcessor.java b/javatests/dagger/internal/codegen/GeneratingProcessor.java
deleted file mode 100644
index 8e4e7b5..0000000
--- a/javatests/dagger/internal/codegen/GeneratingProcessor.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Processor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.TypeElement;
-
-/** A simple {@link Processor} that generates one source file. */
-final class GeneratingProcessor extends AbstractProcessor {
-  private final String generatedClassName;
-  private final String generatedSource;
-  private boolean processed;
-
-  GeneratingProcessor(String generatedClassName, String... source) {
-    this.generatedClassName = generatedClassName;
-    this.generatedSource = Joiner.on("\n").join(source);
-  }
-
-  @Override
-  public SourceVersion getSupportedSourceVersion() {
-    return SourceVersion.latestSupported();
-  }
-
-  @Override
-  public Set<String> getSupportedAnnotationTypes() {
-    return ImmutableSet.of("*");
-  }
-
-  @Override
-  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-    if (!processed) {
-      processed = true;
-      try (Writer writer =
-          processingEnv.getFiler().createSourceFile(generatedClassName).openWriter()) {
-        writer.append(generatedSource);
-      } catch (IOException e) {
-        throw new RuntimeException(e);
-      }
-    }
-    return false;
-  }
-}
diff --git a/javatests/dagger/internal/codegen/GenericMethodsTest.java b/javatests/dagger/internal/codegen/GenericMethodsTest.java
deleted file mode 100644
index cd4595e..0000000
--- a/javatests/dagger/internal/codegen/GenericMethodsTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class GenericMethodsTest {
-  @Test
-  public void parameterizedComponentMethods() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "import java.util.Set;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  <T1> void injectTypeVariable(T1 type);",
-            "  <T2> MembersInjector<T2> membersInjector();",
-            "  <T3> Set<T3> setOfT();",
-            "  <UNUSED> TestComponent unused();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cannot have type variables")
-        .inFile(component)
-        .onLineContaining("<T1>");
-    assertThat(compilation)
-        .hadErrorContaining("cannot have type variables")
-        .inFile(component)
-        .onLineContaining("<T2>");
-    assertThat(compilation)
-        .hadErrorContaining("cannot have type variables")
-        .inFile(component)
-        .onLineContaining("<T3>");
-    assertThat(compilation)
-        .hadErrorContaining("cannot have type variables")
-        .inFile(component)
-        .onLineContaining("<UNUSED>");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java b/javatests/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java
deleted file mode 100644
index e6e9706..0000000
--- a/javatests/dagger/internal/codegen/InjectConstructorFactoryGeneratorTest.java
+++ /dev/null
@@ -1,1410 +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.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
-import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-// TODO(gak): add tests for generation in the default package.
-public final class InjectConstructorFactoryGeneratorTest {
-  private static final JavaFileObject QUALIFIER_A =
-      JavaFileObjects.forSourceLines("test.QualifierA",
-          "package test;",
-          "",
-          "import javax.inject.Qualifier;",
-          "",
-          "@Qualifier @interface QualifierA {}");
-  private static final JavaFileObject QUALIFIER_B =
-      JavaFileObjects.forSourceLines("test.QualifierB",
-          "package test;",
-          "",
-          "import javax.inject.Qualifier;",
-          "",
-          "@Qualifier @interface QualifierB {}");
-  private static final JavaFileObject SCOPE_A =
-      JavaFileObjects.forSourceLines("test.ScopeA",
-          "package test;",
-          "",
-          "import javax.inject.Scope;",
-          "",
-          "@Scope @interface ScopeA {}");
-  private static final JavaFileObject SCOPE_B =
-      JavaFileObjects.forSourceLines("test.ScopeB",
-          "package test;",
-          "",
-          "import javax.inject.Scope;",
-          "",
-          "@Scope @interface ScopeB {}");
-
-  @Test public void injectOnPrivateConstructor() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateConstructor",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class PrivateConstructor {",
-        "  @Inject private PrivateConstructor() {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private constructors")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void injectConstructorOnInnerClass() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class OuterClass {",
-        "  class InnerClass {",
-        "    @Inject InnerClass() {}",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@Inject constructors are invalid on inner classes. "
-                + "Did you mean to make the class static?")
-        .inFile(file)
-        .onLine(7);
-  }
-
-  @Test public void injectConstructorOnAbstractClass() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "abstract class AbstractClass {",
-        "  @Inject AbstractClass() {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Inject is nonsense on the constructor of an abstract class")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void injectConstructorOnGenericClass() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class GenericClass<T> {",
-        "  @Inject GenericClass(T t) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> {",
-            "  private final Provider<T> tProvider;",
-            "",
-            "  public GenericClass_Factory(Provider<T> tProvider) {",
-            "    this.tProvider = tProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public GenericClass<T> get() {",
-            "    return new GenericClass<T>(tProvider.get());",
-            "  }",
-            "",
-            "  public static <T> GenericClass_Factory<T> create(Provider<T> tProvider) {",
-            "    return new GenericClass_Factory<T>(tProvider);",
-            "  }",
-            "",
-            "  public static <T> GenericClass<T> newInstance(T t) {",
-            "    return new GenericClass<T>(t);",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void fieldAndMethodGenerics() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class GenericClass<A, B> {",
-        "  @Inject A a;",
-        "",
-        "  @Inject GenericClass() {}",
-        "",
-        " @Inject void register(B b) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> {",
-            "  private final Provider<A> aProvider;",
-            "  private final Provider<B> bProvider;",
-            "",
-            "  public GenericClass_Factory(",
-            "      Provider<A> aProvider, Provider<B> bProvider) {",
-            "    this.aProvider = aProvider;",
-            "    this.bProvider = bProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public GenericClass<A, B> get() {",
-            "    GenericClass<A, B> instance = new GenericClass<A, B>();",
-            "    GenericClass_MembersInjector.injectA(instance, aProvider.get());",
-            "    GenericClass_MembersInjector.injectRegister(instance, bProvider.get());",
-            "    return instance;",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass_Factory<A, B> create(",
-            "      Provider<A> aProvider, Provider<B> bProvider) {",
-            "    return new GenericClass_Factory<A, B>(aProvider, bProvider);",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass<A, B> newInstance() {",
-            "    return new GenericClass<A, B>();",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void genericClassWithNoDependencies() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class GenericClass<T> {",
-        "  @Inject GenericClass() {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> {",
-            "  @SuppressWarnings(\"rawtypes\")",
-            "  private static final GenericClass_Factory INSTANCE = new GenericClass_Factory();",
-            "",
-            "  @Override",
-            "  public GenericClass<T> get() {",
-            "    return new GenericClass<T>();",
-            "  }",
-            "",
-            "  @SuppressWarnings(\"unchecked\")",
-            "  public static <T> GenericClass_Factory<T> create() {",
-            "    return INSTANCE;",
-            "  }",
-            "",
-            "  public static <T> GenericClass<T> newInstance() {",
-            "    return new GenericClass<T>();",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void twoGenericTypes() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class GenericClass<A, B> {",
-        "  @Inject GenericClass(A a, B b) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> {",
-            "  private final Provider<A> aProvider;",
-            "  private final Provider<B> bProvider;",
-            "",
-            "  public GenericClass_Factory(Provider<A> aProvider, Provider<B> bProvider) {",
-            "    this.aProvider = aProvider;",
-            "    this.bProvider = bProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public GenericClass<A, B> get() {",
-            "    return new GenericClass<A, B>(aProvider.get(), bProvider.get());",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass_Factory<A, B> create(",
-            "      Provider<A> aProvider, Provider<B> bProvider) {",
-            "    return new GenericClass_Factory<A, B>(aProvider, bProvider);",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass<A, B> newInstance(A a, B b) {",
-            "    return new GenericClass<A, B>(a, b);",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void boundedGenerics() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import java.util.List;",
-        "",
-        "class GenericClass<A extends Number & Comparable<A>,",
-        "    B extends List<? extends String>,",
-        "    C extends List<? super String>> {",
-        "  @Inject GenericClass(A a, B b, C c) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import java.util.List;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<A extends Number & Comparable<A>,",
-            "        B extends List<? extends String>,",
-            "        C extends List<? super String>>",
-            "    implements Factory<GenericClass<A, B, C>> {",
-            "  private final Provider<A> aProvider;",
-            "  private final Provider<B> bProvider;",
-            "  private final Provider<C> cProvider;",
-            "",
-            "  public GenericClass_Factory(Provider<A> aProvider,",
-            "      Provider<B> bProvider,",
-            "      Provider<C> cProvider) {",
-            "    this.aProvider = aProvider;",
-            "    this.bProvider = bProvider;",
-            "    this.cProvider = cProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public GenericClass<A, B, C> get() {",
-            "    return new GenericClass<A, B, C>(",
-            "        aProvider.get(), bProvider.get(), cProvider.get());",
-            "  }",
-            "",
-            "  public static <A extends Number & Comparable<A>,",
-            "      B extends List<? extends String>,",
-            "      C extends List<? super String>> GenericClass_Factory<A, B, C> create(",
-            "          Provider<A> aProvider, Provider<B> bProvider, Provider<C> cProvider) {",
-            "    return new GenericClass_Factory<A, B, C>(aProvider, bProvider, cProvider);",
-            "  }",
-            "",
-            "  public static <",
-            "          A extends Number & Comparable<A>,",
-            "          B extends List<? extends String>,",
-            "          C extends List<? super String>>",
-            "      GenericClass<A, B, C> newInstance(A a, B b, C c) {",
-            "    return new GenericClass<A, B, C>(a, b, c);",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void multipleSameTypesWithGenericsAndQualifiersAndLazies() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "import dagger.Lazy;",
-        "",
-        "class GenericClass<A, B> {",
-        "  @Inject GenericClass(A a, A a2, Provider<A> pa, @QualifierA A qa, Lazy<A> la, ",
-        "                       String s, String s2, Provider<String> ps, ",
-        "                       @QualifierA String qs, Lazy<String> ls,",
-        "                       B b, B b2, Provider<B> pb, @QualifierA B qb, Lazy<B> lb) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.GenericClass_Factory",
-            "package test;",
-            "",
-            "import dagger.Lazy;",
-            "import dagger.internal.DoubleCheck;",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class GenericClass_Factory<A, B>",
-            "    implements Factory<GenericClass<A, B>> {",
-            "  private final Provider<A> aAndA2AndPaAndLaProvider;",
-            "  private final Provider<A> qaProvider;",
-            "  private final Provider<String> sAndS2AndPsAndLsProvider;",
-            "  private final Provider<String> qsProvider;",
-            "  private final Provider<B> bAndB2AndPbAndLbProvider;",
-            "  private final Provider<B> qbProvider;",
-            "",
-            "  public GenericClass_Factory(Provider<A> aAndA2AndPaAndLaProvider,",
-            "      Provider<A> qaProvider,",
-            "      Provider<String> sAndS2AndPsAndLsProvider,",
-            "      Provider<String> qsProvider,",
-            "      Provider<B> bAndB2AndPbAndLbProvider,",
-            "      Provider<B> qbProvider) {",
-            "    this.aAndA2AndPaAndLaProvider = aAndA2AndPaAndLaProvider;",
-            "    this.qaProvider = qaProvider;",
-            "    this.sAndS2AndPsAndLsProvider = sAndS2AndPsAndLsProvider;",
-            "    this.qsProvider = qsProvider;",
-            "    this.bAndB2AndPbAndLbProvider = bAndB2AndPbAndLbProvider;",
-            "    this.qbProvider = qbProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public GenericClass<A, B> get() {",
-            "    return new GenericClass<A, B>(",
-            "      aAndA2AndPaAndLaProvider.get(),",
-            "      aAndA2AndPaAndLaProvider.get(),",
-            "      aAndA2AndPaAndLaProvider,",
-            "      qaProvider.get(),",
-            "      DoubleCheck.lazy(aAndA2AndPaAndLaProvider),",
-            "      sAndS2AndPsAndLsProvider.get(),",
-            "      sAndS2AndPsAndLsProvider.get(),",
-            "      sAndS2AndPsAndLsProvider,",
-            "      qsProvider.get(),",
-            "      DoubleCheck.lazy(sAndS2AndPsAndLsProvider),",
-            "      bAndB2AndPbAndLbProvider.get(),",
-            "      bAndB2AndPbAndLbProvider.get(),",
-            "      bAndB2AndPbAndLbProvider,",
-            "      qbProvider.get(),",
-            "      DoubleCheck.lazy(bAndB2AndPbAndLbProvider));",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass_Factory<A, B> create(",
-            "      Provider<A> aAndA2AndPaAndLaProvider,",
-            "      Provider<A> qaProvider,",
-            "      Provider<String> sAndS2AndPsAndLsProvider,",
-            "      Provider<String> qsProvider,",
-            "      Provider<B> bAndB2AndPbAndLbProvider,",
-            "      Provider<B> qbProvider) {",
-            "    return new GenericClass_Factory<A, B>(",
-            "        aAndA2AndPaAndLaProvider,",
-            "        qaProvider,",
-            "        sAndS2AndPsAndLsProvider,",
-            "        qsProvider,",
-            "        bAndB2AndPbAndLbProvider,",
-            "        qbProvider);",
-            "  }",
-            "",
-            "  public static <A, B> GenericClass<A, B> newInstance(",
-            "      A a,",
-            "      A a2,",
-            "      Provider<A> pa,",
-            "      A qa,",
-            "      Lazy<A> la,",
-            "      String s,",
-            "      String s2,",
-            "      Provider<String> ps,",
-            "      String qs,",
-            "      Lazy<String> ls,",
-            "      B b,",
-            "      B b2,",
-            "      Provider<B> pb,",
-            "      B qb,",
-            "      Lazy<B> lb) {",
-            "    return new GenericClass<A, B>(",
-            "        a, a2, pa, qa, la, s, s2, ps, qs, ls, b, b2, pb, qb, lb);",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void multipleInjectConstructors() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.TooManyInjectConstructors",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class TooManyInjectConstructors {",
-        "  @Inject TooManyInjectConstructors() {}",
-        "  TooManyInjectConstructors(int i) {}",
-        "  @Inject TooManyInjectConstructors(String s) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Types may only contain one @Inject constructor")
-        .inFile(file)
-        .onLine(6);
-    assertThat(compilation)
-        .hadErrorContaining("Types may only contain one @Inject constructor")
-        .inFile(file)
-        .onLine(8);
-  }
-
-  @Test public void multipleQualifiersOnInjectConstructorParameter() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierConstructorParam",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class MultipleQualifierConstructorParam {",
-        "  @Inject MultipleQualifierConstructorParam(@QualifierA @QualifierB String s) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    // for whatever reason, javac only reports the error once on the constructor
-    assertThat(compilation)
-        .hadErrorContaining("A single dependency request may not use more than one @Qualifier")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void injectConstructorOnClassWithMultipleScopes() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "@ScopeA @ScopeB class MultipleScopeClass {",
-        "  @Inject MultipleScopeClass() {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file, SCOPE_A, SCOPE_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("A single binding may not declare more than one @Scope")
-        .inFile(file)
-        .onLine(5)
-        .atColumn(1);
-    assertThat(compilation)
-        .hadErrorContaining("A single binding may not declare more than one @Scope")
-        .inFile(file)
-        .onLine(5)
-        .atColumn(9);
-  }
-
-  @Test public void injectConstructorWithQualifier() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class MultipleScopeClass {",
-        "  @Inject",
-        "  @QualifierA",
-        "  @QualifierB",
-        "  MultipleScopeClass() {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Qualifier annotations are not allowed on @Inject constructors")
-        .inFile(file)
-        .onLine(7);
-    assertThat(compilation)
-        .hadErrorContaining("@Qualifier annotations are not allowed on @Inject constructors")
-        .inFile(file)
-        .onLine(8);
-  }
-
-  @Test public void injectConstructorWithCheckedExceptionsError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.CheckedExceptionClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class CheckedExceptionClass {",
-        "  @Inject CheckedExceptionClass() throws Exception {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support checked exceptions on @Inject constructors")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void injectConstructorWithCheckedExceptionsWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.CheckedExceptionClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class CheckedExceptionClass {",
-        "  @Inject CheckedExceptionClass() throws Exception {}",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.privateMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining("Dagger does not support checked exceptions on @Inject constructors")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateInjectClassError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class InnerClass {",
-        "    @Inject InnerClass() {}",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(7);
-  }
-
-  @Test public void privateInjectClassWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class InnerClass {",
-        "    @Inject InnerClass() {}",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.privateMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(7);
-  }
-
-  @Test public void nestedInPrivateInjectClassError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class MiddleClass {",
-        "    static final class InnerClass {",
-        "      @Inject InnerClass() {}",
-        "    }",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(8);
-  }
-
-  @Test public void nestedInPrivateInjectClassWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class MiddleClass {",
-        "    static final class InnerClass {",
-        "      @Inject InnerClass() {}",
-        "    }",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.privateMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(8);
-  }
-
-  @Test public void finalInjectField() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.FinalInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class FinalInjectField {",
-        "  @Inject final String s;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Inject fields may not be final")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateInjectFieldError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class PrivateInjectField {",
-        "  @Inject private String s;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private fields")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateInjectFieldWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class PrivateInjectField {",
-        "  @Inject private String s;",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.privateMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded(); // TODO: Verify warning message when supported
-  }
-
-  @Test public void staticInjectFieldError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class StaticInjectField {",
-        "  @Inject static String s;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into static fields")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void staticInjectFieldWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class StaticInjectField {",
-        "  @Inject static String s;",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.staticMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded(); // TODO: Verify warning message when supported
-  }
-
-  @Test public void multipleQualifiersOnField() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierInjectField",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class MultipleQualifierInjectField {",
-        "  @Inject @QualifierA @QualifierB String s;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("A single dependency request may not use more than one @Qualifier")
-        .inFile(file)
-        .onLine(6)
-        .atColumn(11);
-    assertThat(compilation)
-        .hadErrorContaining("A single dependency request may not use more than one @Qualifier")
-        .inFile(file)
-        .onLine(6)
-        .atColumn(23);
-  }
-
-  @Test public void abstractInjectMethod() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "abstract class AbstractInjectMethod {",
-        "  @Inject abstract void method();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Methods with @Inject may not be abstract")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateInjectMethodError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class PrivateInjectMethod {",
-        "  @Inject private void method(){}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private methods")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateInjectMethodWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class PrivateInjectMethod {",
-        "  @Inject private void method(){}",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.privateMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded(); // TODO: Verify warning message when supported
-  }
-
-  @Test public void staticInjectMethodError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class StaticInjectMethod {",
-        "  @Inject static void method(){}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into static methods")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void staticInjectMethodWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class StaticInjectMethod {",
-        "  @Inject static void method(){}",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions("-Adagger.staticMemberValidation=WARNING").compile(file);
-    assertThat(compilation).succeeded(); // TODO: Verify warning message when supported
-  }
-
-  @Test public void genericInjectMethod() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericInjectMethod",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class AbstractInjectMethod {",
-        "  @Inject <T> void method();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Methods with @Inject may not declare type parameters")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void multipleQualifiersOnInjectMethodParameter() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierMethodParam",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class MultipleQualifierMethodParam {",
-        "  @Inject void method(@QualifierA @QualifierB String s) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("A single dependency request may not use more than one @Qualifier")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void injectConstructorDependsOnProduced() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Produced;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A(Produced<String> str) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Produced may only be injected in @Produces methods");
-  }
-
-  @Test public void injectConstructorDependsOnProducer() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Producer;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A(Producer<String> str) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Producer may only be injected in @Produces methods");
-  }
-
-  @Test public void injectFieldDependsOnProduced() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Produced;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject Produced<String> str;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Produced may only be injected in @Produces methods");
-  }
-
-  @Test public void injectFieldDependsOnProducer() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Producer;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject Producer<String> str;",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Producer may only be injected in @Produces methods");
-  }
-
-  @Test public void injectMethodDependsOnProduced() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Produced;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject void inject(Produced<String> str) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Produced may only be injected in @Produces methods");
-  }
-
-  @Test public void injectMethodDependsOnProducer() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import dagger.producers.Producer;",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject void inject(Producer<String> str) {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(aFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Producer may only be injected in @Produces methods");
-  }
-
-  @Test public void injectConstructor() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class InjectConstructor {",
-        "  @Inject InjectConstructor(String s) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectConstructor_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectConstructor_Factory ",
-            "    implements Factory<InjectConstructor> {",
-            "",
-            "  private final Provider<String> sProvider;",
-            "",
-            "  public InjectConstructor_Factory(Provider<String> sProvider) {",
-            "    this.sProvider = sProvider;",
-            "  }",
-            "",
-            "  @Override public InjectConstructor get() {",
-            "    return new InjectConstructor(sProvider.get());",
-            "  }",
-            "",
-            "  public static InjectConstructor_Factory create(Provider<String> sProvider) {",
-            "    return new InjectConstructor_Factory(sProvider);",
-            "  }",
-            "",
-            "  public static InjectConstructor newInstance(String s) {",
-            "    return new InjectConstructor(s);",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test public void injectConstructorAndMembersInjection() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.AllInjections",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class AllInjections {",
-        "  @Inject String s;",
-        "  @Inject AllInjections(String s) {}",
-        "  @Inject void s(String s) {}",
-        "}");
-    JavaFileObject expectedFactory =
-        JavaFileObjects.forSourceLines(
-            "test.AllInjections_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class AllInjections_Factory implements Factory<AllInjections> {",
-            "  private final Provider<String> sProvider;",
-            "",
-            "  public AllInjections_Factory(Provider<String> sProvider) {",
-            "    this.sProvider = sProvider;",
-            "  }",
-            "",
-            "  @Override public AllInjections get() {",
-            "    AllInjections instance = new AllInjections(sProvider.get());",
-            "    AllInjections_MembersInjector.injectS(instance, sProvider.get());",
-            "    AllInjections_MembersInjector.injectS2(instance, sProvider.get());",
-            "    return instance;",
-            "  }",
-            "",
-            "  public static AllInjections_Factory create(Provider<String> sProvider) {",
-            "    return new AllInjections_Factory(sProvider);",
-            "  }",
-            "",
-            "  public static AllInjections newInstance(String s) {",
-            "     return new AllInjections(s);",
-            "   }",
-            "}");
-    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expectedFactory);
-  }
-
-  @Test
-  public void wildcardDependency() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
-        "package test;",
-        "",
-        "import java.util.List;",
-        "import javax.inject.Inject;",
-        "",
-        "class InjectConstructor {",
-        "  @Inject InjectConstructor(List<?> objects) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectConstructor_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import java.util.List;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectConstructor_Factory ",
-            "    implements Factory<InjectConstructor> {",
-            "",
-            "  private final Provider<List<?>> objectsProvider;",
-            "",
-            "  public InjectConstructor_Factory(Provider<List<?>> objectsProvider) {",
-            "    this.objectsProvider = objectsProvider;",
-            "  }",
-            "",
-            "  @Override public InjectConstructor get() {",
-            "    return new InjectConstructor(objectsProvider.get());",
-            "  }",
-            "",
-            "  public static InjectConstructor_Factory create(",
-            "      Provider<List<?>> objectsProvider) {",
-            "    return new InjectConstructor_Factory(objectsProvider);",
-            "  }",
-            "",
-            "  public static InjectConstructor newInstance(List<?> objects) {",
-            "    return new InjectConstructor(objects);",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test
-  public void basicNameCollision() {
-    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Factory",
-        "package other.pkg;",
-        "",
-        "public class Factory {}");
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import other.pkg.Factory;",
-        "",
-        "class InjectConstructor {",
-        "  @Inject InjectConstructor(Factory factory) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectConstructor_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectConstructor_Factory ",
-            "    implements Factory<InjectConstructor> {",
-            "",
-            "  private final Provider<other.pkg.Factory> factoryProvider;",
-            "",
-            "  public InjectConstructor_Factory(Provider<other.pkg.Factory> factoryProvider) {",
-            "    this.factoryProvider = factoryProvider;",
-            "  }",
-            "",
-            "  @Override public InjectConstructor get() {",
-            "    return new InjectConstructor(factoryProvider.get());",
-            "  }",
-            "",
-            "  public static InjectConstructor_Factory create(",
-            "      Provider<other.pkg.Factory> factoryProvider) {",
-            "    return new InjectConstructor_Factory(factoryProvider);",
-            "  }",
-            "",
-            "  public static InjectConstructor newInstance(",
-            "      other.pkg.Factory factory) {",
-            "    return new InjectConstructor(factory);",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test
-  public void nestedNameCollision() {
-    JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Outer",
-        "package other.pkg;",
-        "",
-        "public class Outer {",
-        "  public class Factory {}",
-        "}");
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import other.pkg.Outer;",
-        "",
-        "class InjectConstructor {",
-        "  @Inject InjectConstructor(Outer.Factory factory) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectConstructor_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "import other.pkg.Outer;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectConstructor_Factory ",
-            "    implements Factory<InjectConstructor> {",
-            "",
-            "  private final Provider<Outer.Factory> factoryProvider;",
-            "",
-            "  public InjectConstructor_Factory(Provider<Outer.Factory> factoryProvider) {",
-            "    this.factoryProvider = factoryProvider;",
-            "  }",
-            "",
-            "  @Override public InjectConstructor get() {",
-            "    return new InjectConstructor(factoryProvider.get());",
-            "  }",
-            "",
-            "  public static InjectConstructor_Factory create(",
-            "      Provider<Outer.Factory> factoryProvider) {",
-            "    return new InjectConstructor_Factory(factoryProvider);",
-            "  }",
-            "",
-            "  public static InjectConstructor newInstance(",
-            "      Outer.Factory factory) {",
-            "    return new InjectConstructor(factory);",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test
-  public void samePackageNameCollision() {
-    JavaFileObject samePackageInterface = JavaFileObjects.forSourceLines("test.CommonName",
-        "package test;",
-        "",
-        "public interface CommonName {}");
-    JavaFileObject differentPackageInterface = JavaFileObjects.forSourceLines(
-        "other.pkg.CommonName",
-        "package other.pkg;",
-        "",
-        "public interface CommonName {}");
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class InjectConstructor implements CommonName {",
-        "  @Inject InjectConstructor(other.pkg.CommonName otherPackage, CommonName samePackage) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.InjectConstructor_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectConstructor_Factory ",
-            "    implements Factory<InjectConstructor> {",
-            "",
-            "  private final Provider<other.pkg.CommonName> otherPackageProvider;",
-            "  private final Provider<CommonName> samePackageProvider;",
-            "",
-            "  public InjectConstructor_Factory(",
-            "      Provider<other.pkg.CommonName> otherPackageProvider,",
-            "      Provider<CommonName> samePackageProvider) {",
-            "    this.otherPackageProvider = otherPackageProvider;",
-            "    this.samePackageProvider = samePackageProvider;",
-            "  }",
-            "",
-            "  @Override public InjectConstructor get() {",
-            "    return new InjectConstructor(",
-            "        otherPackageProvider.get(), samePackageProvider.get());",
-            "  }",
-            "",
-            "  public static InjectConstructor_Factory create(",
-            "      Provider<other.pkg.CommonName> otherPackageProvider,",
-            "      Provider<CommonName> samePackageProvider) {",
-            "    return new InjectConstructor_Factory(otherPackageProvider, samePackageProvider);",
-            "  }",
-            "",
-            "  public static InjectConstructor newInstance(",
-            "      other.pkg.CommonName otherPackage, CommonName samePackage) {",
-            "    return new InjectConstructor(otherPackage, samePackage);",
-            "  }",
-            "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(samePackageInterface, differentPackageInterface, file))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(expected);
-  }
-
-  @Test
-  public void noDeps() {
-    JavaFileObject simpleType = JavaFileObjects.forSourceLines("test.SimpleType",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class SimpleType {",
-        "  @Inject SimpleType() {}",
-        "}");
-    JavaFileObject factory =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleType_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class SimpleType_Factory implements Factory<SimpleType> {",
-            "  private static final SimpleType_Factory INSTANCE = new SimpleType_Factory();",
-            "",
-            "  @Override public SimpleType get() {",
-            "    return new SimpleType();",
-            "  }",
-            "",
-            "  public static SimpleType_Factory create() {",
-            "    return INSTANCE;",
-            "  }",
-            "",
-            "  public static SimpleType newInstance() {",
-            "    return new SimpleType();",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(simpleType)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factory);
-  }
-
-  @Test public void simpleComponentWithNesting() {
-    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines("test.OuterType",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterType {",
-        "  static class A {",
-        "    @Inject A() {}",
-        "  }",
-        "  static class B {",
-        "    @Inject A a;",
-        "  }",
-        "}");
-    JavaFileObject aFactory =
-        JavaFileObjects.forSourceLines(
-            "test.OuterType_A_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class OuterType_A_Factory implements Factory<OuterType.A> {",
-            "  private static final OuterType_A_Factory INSTANCE = new OuterType_A_Factory();",
-            "",
-            "  @Override public OuterType.A get() {",
-            "    return new OuterType.A();",
-            "  }",
-            "",
-            "  public static OuterType_A_Factory create() {",
-            "    return INSTANCE;",
-            "  }",
-            "",
-            "  public static OuterType.A newInstance() {",
-            "    return new OuterType.A();",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(ImmutableList.of(nestedTypesFile))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(aFactory);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/JavaFileBuilder.java b/javatests/dagger/internal/codegen/JavaFileBuilder.java
deleted file mode 100644
index f682b0c..0000000
--- a/javatests/dagger/internal/codegen/JavaFileBuilder.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.common.collect.ImmutableList;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import javax.tools.JavaFileObject;
-
-/**
- * A fluent API to build a {@link JavaFileObject} appropriate for a current set of settings, such as
- * compiler mode.
- *
- * <p>After creating a builder, you can add lines to the file. Call {@link #addLines(String...)} to
- * add lines irrespective of the settings. If you want to add different lines for different possible
- * settings, call {@link #addLinesIf(Object, String...)} to add those lines only if the given
- * setting has been added via {@link #withSetting(Object)} or {@link #withSettings(Object...)}.
- */
-final class JavaFileBuilder {
-  private final String qualifiedName;
-  private final Set<Object> settings = new HashSet<>();
-
-  private final ImmutableList.Builder<String> sourceLines = ImmutableList.builder();
-
-  /** Creates a builder for a file whose top level type has a given qualified name. */
-  JavaFileBuilder(String qualifiedName) {
-    checkArgument(!qualifiedName.isEmpty());
-    this.qualifiedName = qualifiedName;
-  }
-
-  // TODO(cgdecker): Get rid of the special constructor/method for CompilerMode
-
-  /** Creates a builder for a file whose top level type has a given qualified name. */
-  JavaFileBuilder(CompilerMode compilerMode, String qualifiedName) {
-    this(qualifiedName);
-    settings.add(compilerMode);
-  }
-
-  /** Adds the given setting as one that code should be generated for. */
-  JavaFileBuilder withSetting(Object setting) {
-    this.settings.add(setting);
-    return this;
-  }
-
-  /** Adds the given settings as one that code should be generated for. */
-  JavaFileBuilder withSettings(Object s1, Object s2, Object... more) {
-    settings.add(s1);
-    settings.add(s2);
-    Collections.addAll(settings, more);
-    return this;
-  }
-
-  /** Adds lines no matter what the {@link CompilerMode} is. */
-  JavaFileBuilder addLines(String... lines) {
-    sourceLines.add(lines);
-    return this;
-  }
-
-  /** Adds lines if in the given mode. */
-  JavaFileBuilder addLinesIn(CompilerMode mode, String... lines) {
-    return addLinesIf(mode, lines);
-  }
-
-  /** Adds lines if in the given setting is set. */
-  JavaFileBuilder addLinesIf(Object setting, String... lines) {
-    if (settings.contains(setting)) {
-      sourceLines.add(lines);
-    }
-    return this;
-  }
-
-  /** Builds the {@link JavaFileObject}. */
-  JavaFileObject build() {
-    return JavaFileObjects.forSourceLines(qualifiedName, sourceLines.build());
-  }
-}
diff --git a/javatests/dagger/internal/codegen/KeyFactoryTest.java b/javatests/dagger/internal/codegen/KeyFactoryTest.java
deleted file mode 100644
index d526ec9..0000000
--- a/javatests/dagger/internal/codegen/KeyFactoryTest.java
+++ /dev/null
@@ -1,332 +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.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.testing.compile.CompilationRule;
-import dagger.Module;
-import dagger.Provides;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.model.Key;
-import dagger.model.Key.MultibindingContributionIdentifier;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
-import dagger.producers.ProducerModule;
-import dagger.producers.Produces;
-import java.lang.annotation.Retention;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Qualifier;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link Key}.
- */
-@RunWith(JUnit4.class)
-public class KeyFactoryTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-
-  private DaggerElements elements;
-  private DaggerTypes types;
-  private KeyFactory keyFactory;
-
-  @Before public void setUp() {
-    this.elements = new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
-    this.types = new DaggerTypes(compilationRule.getTypes(), elements);
-    TypeProtoConverter typeProtoConverter = new TypeProtoConverter(types, elements);
-    this.keyFactory = new KeyFactory(
-        types, elements, typeProtoConverter, new AnnotationProtoConverter(typeProtoConverter));
-  }
-
-  @Test public void forInjectConstructorWithResolvedType() {
-    TypeElement typeElement =
-        compilationRule.getElements().getTypeElement(InjectedClass.class.getCanonicalName());
-    ExecutableElement constructor =
-        Iterables.getOnlyElement(ElementFilter.constructorsIn(typeElement.getEnclosedElements()));
-    Key key =
-        keyFactory.forInjectConstructorWithResolvedType(constructor.getEnclosingElement().asType());
-    assertThat(key).isEqualTo(Key.builder(typeElement.asType()).build());
-    assertThat(key.toString()).isEqualTo("dagger.internal.codegen.KeyFactoryTest.InjectedClass");
-  }
-
-  static final class InjectedClass {
-    @SuppressWarnings("unused")
-    @Inject InjectedClass(String s, int i) {}
-  }
-
-  @Test public void forProvidesMethod() {
-    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeElement moduleElement =
-        elements.getTypeElement(ProvidesMethodModule.class.getCanonicalName());
-    ExecutableElement providesMethod =
-        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
-    Key key = keyFactory.forProvidesMethod(providesMethod, moduleElement);
-    assertThat(key).isEqualTo(Key.builder(stringType).build());
-    assertThat(key.toString()).isEqualTo("java.lang.String");
-  }
-
-  @Module
-  static final class ProvidesMethodModule {
-    @Provides String provideString() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  @Test public void forProvidesMethod_qualified() {
-    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeElement qualifierElement =
-        elements.getTypeElement(TestQualifier.class.getCanonicalName());
-    TypeElement moduleElement =
-        elements.getTypeElement(QualifiedProvidesMethodModule.class.getCanonicalName());
-    ExecutableElement providesMethod =
-        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
-    Key key = keyFactory.forProvidesMethod(providesMethod, moduleElement);
-    assertThat(MoreTypes.equivalence().wrap(key.qualifier().get().getAnnotationType()))
-        .isEqualTo(MoreTypes.equivalence().wrap(qualifierElement.asType()));
-    assertThat(MoreTypes.equivalence().wrap(key.type()))
-        .isEqualTo(MoreTypes.equivalence().wrap(stringType));
-    assertThat(key.toString())
-        .isEqualTo(
-            "@dagger.internal.codegen.KeyFactoryTest.TestQualifier({"
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=1, value=\"value a\"), "
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=2, value=\"value b\"), "
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=3145, value=\"default\")"
-                + "}) java.lang.String");
-  }
-
-  @Test public void qualifiedKeyEquivalents() {
-    TypeElement moduleElement =
-        elements.getTypeElement(QualifiedProvidesMethodModule.class.getCanonicalName());
-    ExecutableElement providesMethod =
-        Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements()));
-    Key provisionKey = keyFactory.forProvidesMethod(providesMethod, moduleElement);
-
-    TypeMirror type = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeElement injectableElement =
-        elements.getTypeElement(QualifiedFieldHolder.class.getCanonicalName());
-    Element injectionField =
-        Iterables.getOnlyElement(ElementFilter.fieldsIn(injectableElement.getEnclosedElements()));
-    AnnotationMirror qualifier = Iterables.getOnlyElement(injectionField.getAnnotationMirrors());
-    Key injectionKey = Key.builder(type).qualifier(qualifier).build();
-
-    assertThat(provisionKey).isEqualTo(injectionKey);
-    assertThat(injectionKey.toString())
-        .isEqualTo(
-            "@dagger.internal.codegen.KeyFactoryTest.TestQualifier({"
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=1, value=\"value a\"), "
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=2, value=\"value b\"), "
-                + "@dagger.internal.codegen.KeyFactoryTest.InnerAnnotation("
-                + "param1=3145, value=\"default\")"
-                + "}) java.lang.String");
-  }
-
-  @Module
-  static final class QualifiedProvidesMethodModule {
-    @Provides
-    @TestQualifier({
-      @InnerAnnotation(value = "value a", param1 = 1),
-      // please note the order of 'param' and 'value' is inverse
-      @InnerAnnotation(param1 = 2, value = "value b"),
-      @InnerAnnotation()
-    })
-    static String provideQualifiedString() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  static final class QualifiedFieldHolder {
-    @TestQualifier({
-      @InnerAnnotation(value = "value a", param1 = 1),
-      // please note the order of 'param' and 'value' is inverse
-      @InnerAnnotation(param1 = 2, value = "value b"),
-      @InnerAnnotation()
-    })
-    String aString;
-  }
-
-  @Retention(RUNTIME)
-  @Qualifier
-  @interface TestQualifier {
-    InnerAnnotation[] value();
-  }
-
-  @interface InnerAnnotation {
-    int param1() default 3145;
-
-    String value() default "default";
-  }
-
-  @Test public void forProvidesMethod_sets() {
-    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());
-    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeMirror setOfStringsType = types.getDeclaredType(setElement, stringType);
-    TypeElement moduleElement =
-        elements.getTypeElement(SetProvidesMethodsModule.class.getCanonicalName());
-    for (ExecutableElement providesMethod
-        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
-      Key key = keyFactory.forProvidesMethod(providesMethod, moduleElement);
-      assertThat(key)
-          .isEqualTo(
-              Key.builder(setOfStringsType)
-                  .multibindingContributionIdentifier(
-                      new MultibindingContributionIdentifier(providesMethod, moduleElement))
-                  .build());
-      assertThat(key.toString())
-          .isEqualTo(
-              String.format(
-                  "java.util.Set<java.lang.String> "
-                      + "dagger.internal.codegen.KeyFactoryTest.SetProvidesMethodsModule#%s",
-                  providesMethod.getSimpleName()));
-    }
-  }
-
-  @Module
-  static final class SetProvidesMethodsModule {
-    @Provides @IntoSet String provideString() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Provides @ElementsIntoSet Set<String> provideStrings() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  @Module
-  static final class PrimitiveTypes {
-    @Provides int foo() {
-      return 0;
-    }
-  }
-
-  @Module
-  static final class BoxedPrimitiveTypes {
-    @Provides Integer foo() {
-      return 0;
-    }
-  }
-
-  @Test public void primitiveKeysMatchBoxedKeys() {
-    TypeElement primitiveHolder = elements.getTypeElement(PrimitiveTypes.class.getCanonicalName());
-    ExecutableElement intMethod =
-        Iterables.getOnlyElement(ElementFilter.methodsIn(primitiveHolder.getEnclosedElements()));
-    TypeElement boxedPrimitiveHolder =
-        elements.getTypeElement(BoxedPrimitiveTypes.class.getCanonicalName());
-    ExecutableElement integerMethod = Iterables.getOnlyElement(
-        ElementFilter.methodsIn(boxedPrimitiveHolder.getEnclosedElements()));
-
-    // TODO(cgruber): Truth subject for TypeMirror and TypeElement
-    TypeMirror intType = intMethod.getReturnType();
-    assertThat(intType.getKind().isPrimitive()).isTrue();
-    TypeMirror integerType = integerMethod.getReturnType();
-    assertThat(integerType.getKind().isPrimitive()).isFalse();
-    assertWithMessage("type equality").that(types.isSameType(intType, integerType)).isFalse();
-    Key intKey = keyFactory.forProvidesMethod(intMethod, primitiveHolder);
-    Key integerKey = keyFactory.forProvidesMethod(integerMethod, boxedPrimitiveHolder);
-    assertThat(intKey).isEqualTo(integerKey);
-    assertThat(intKey.toString()).isEqualTo("java.lang.Integer");
-    assertThat(integerKey.toString()).isEqualTo("java.lang.Integer");
-  }
-
-  @Test public void forProducesMethod() {
-    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeElement moduleElement =
-        elements.getTypeElement(ProducesMethodsModule.class.getCanonicalName());
-    for (ExecutableElement producesMethod
-        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
-      Key key = keyFactory.forProducesMethod(producesMethod, moduleElement);
-      assertThat(key).isEqualTo(Key.builder(stringType).build());
-      assertThat(key.toString()).isEqualTo("java.lang.String");
-    }
-  }
-
-  @ProducerModule
-  static final class ProducesMethodsModule {
-    @Produces String produceString() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Produces ListenableFuture<String> produceFutureString() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  @Test public void forProducesMethod_sets() {
-    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());
-    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
-    TypeMirror setOfStringsType = types.getDeclaredType(setElement, stringType);
-    TypeElement moduleElement =
-        elements.getTypeElement(SetProducesMethodsModule.class.getCanonicalName());
-    for (ExecutableElement producesMethod
-        : ElementFilter.methodsIn(moduleElement.getEnclosedElements())) {
-      Key key = keyFactory.forProducesMethod(producesMethod, moduleElement);
-      assertThat(key)
-          .isEqualTo(
-              Key.builder(setOfStringsType)
-                  .multibindingContributionIdentifier(
-                      new MultibindingContributionIdentifier(producesMethod, moduleElement))
-                  .build());
-      assertThat(key.toString())
-          .isEqualTo(
-              String.format(
-                  "java.util.Set<java.lang.String> "
-                      + "dagger.internal.codegen.KeyFactoryTest.SetProducesMethodsModule#%s",
-                  producesMethod.getSimpleName()));
-    }
-  }
-
-  @ProducerModule
-  static final class SetProducesMethodsModule {
-    @Produces @IntoSet String produceString() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Produces @IntoSet ListenableFuture<String> produceFutureString() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Produces @ElementsIntoSet Set<String> produceStrings() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Produces @ElementsIntoSet
-    ListenableFuture<Set<String>> produceFutureStrings() {
-      throw new UnsupportedOperationException();
-    }
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MapBindingComponentProcessorTest.java b/javatests/dagger/internal/codegen/MapBindingComponentProcessorTest.java
deleted file mode 100644
index ad48712..0000000
--- a/javatests/dagger/internal/codegen/MapBindingComponentProcessorTest.java
+++ /dev/null
@@ -1,1101 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MapBindingComponentProcessorTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public MapBindingComponentProcessorTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void mapBindingsWithEnumKey() {
-    JavaFileObject mapModuleOneFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleOne",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.IntoMap;",
-                "",
-                "@Module",
-                "final class MapModuleOne {",
-                "  @Provides @IntoMap @PathKey(PathEnum.ADMIN) Handler provideAdminHandler() {",
-                "    return new AdminHandler();",
-                "  }",
-                "}");
-    JavaFileObject mapModuleTwoFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleTwo",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.IntoMap;",
-                "",
-                "@Module",
-                "final class MapModuleTwo {",
-                "  @Provides @IntoMap @PathKey(PathEnum.LOGIN) Handler provideLoginHandler() {",
-                "    return new LoginHandler();",
-                "  }",
-                "}");
-    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
-        "package test;",
-        "import dagger.MapKey;",
-        "import java.lang.annotation.Retention;",
-        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-        "",
-        "@MapKey(unwrapValue = true)",
-        "@Retention(RUNTIME)",
-        "public @interface PathKey {",
-        "  PathEnum value();",
-        "}");
-    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
-        "package test;",
-        "",
-        "public enum PathEnum {",
-        "    ADMIN,",
-        "    LOGIN;",
-        "}");
-
-    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
-        "package test;",
-        "",
-        "interface Handler {}");
-    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
-        "package test;",
-        "",
-        "class LoginHandler implements Handler {",
-        "  public LoginHandler() {}",
-        "}");
-    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
-        "package test;",
-        "",
-        "class AdminHandler implements Handler {",
-        "  public AdminHandler() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
-        "interface TestComponent {",
-        "  Provider<Map<PathEnum, Provider<Handler>>> dispatcher();",
-        "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final MapModuleOne mapModuleOne;",
-                "  private final MapModuleTwo mapModuleTwo;",
-                "  private volatile Provider<Handler> provideAdminHandlerProvider;",
-                "  private volatile Provider<Handler> provideLoginHandlerProvider;",
-                "  private volatile Provider<Map<PathEnum, Provider<Handler>>>",
-                "      mapOfPathEnumAndProviderOfHandlerProvider;",
-                "",
-                "  private Provider<Handler> getProvideAdminHandlerProvider() {",
-                "    Object local = provideAdminHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(1);",
-                "      provideAdminHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Provider<Handler> getProvideLoginHandlerProvider() {",
-                "    Object local = provideLoginHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      provideLoginHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Map<PathEnum, Provider<Handler>>",
-                "        getMapOfPathEnumAndProviderOfHandler() {",
-                "    return ImmutableMap.<PathEnum, Provider<Handler>>of(",
-                "        PathEnum.ADMIN, getProvideAdminHandlerProvider(),",
-                "        PathEnum.LOGIN, getProvideLoginHandlerProvider());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<PathEnum, Provider<Handler>>> dispatcher() {",
-                "    Object local = mapOfPathEnumAndProviderOfHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      mapOfPathEnumAndProviderOfHandlerProvider =",
-                "          (Provider<Map<PathEnum, Provider<Handler>>>) local;",
-                "    }",
-                "    return (Provider<Map<PathEnum, Provider<Handler>>>) local;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "            return (T) DaggerTestComponent.this",
-                "                 .getMapOfPathEnumAndProviderOfHandler();",
-                "        case 1:",
-                "            return (T) MapModuleOne_ProvideAdminHandlerFactory",
-                "                .provideAdminHandler(DaggerTestComponent.this.mapModuleOne);",
-                "        case 2:",
-                "            return (T) MapModuleTwo_ProvideLoginHandlerFactory",
-                "                .provideLoginHandler(DaggerTestComponent.this.mapModuleTwo);",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<Handler> provideAdminHandlerProvider;",
-                "  private Provider<Handler> provideLoginHandlerProvider;",
-                "  private Provider<Map<PathEnum, Provider<Handler>>>",
-                "      mapOfPathEnumAndProviderOfHandlerProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "      final MapModuleOne mapModuleOneParam,",
-                "      final MapModuleTwo mapModuleTwoParam) {",
-                "    this.provideAdminHandlerProvider =",
-                "        MapModuleOne_ProvideAdminHandlerFactory.create(mapModuleOneParam);",
-                "    this.provideLoginHandlerProvider =",
-                "        MapModuleTwo_ProvideLoginHandlerFactory.create(mapModuleTwoParam);",
-                "    this.mapOfPathEnumAndProviderOfHandlerProvider =",
-                "        MapProviderFactory.<PathEnum, Handler>builder(2)",
-                "            .put(PathEnum.ADMIN, provideAdminHandlerProvider)",
-                "            .put(PathEnum.LOGIN, provideLoginHandlerProvider)",
-                "            .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<PathEnum, Provider<Handler>>> dispatcher() {",
-                "    return mapOfPathEnumAndProviderOfHandlerProvider;",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                mapModuleOneFile,
-                mapModuleTwoFile,
-                enumKeyFile,
-                pathEnumFile,
-                HandlerFile,
-                LoginHandlerFile,
-                AdminHandlerFile,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void mapBindingsWithInaccessibleKeys() {
-    JavaFileObject mapKeys =
-        JavaFileObjects.forSourceLines(
-            "mapkeys.MapKeys",
-            "package mapkeys;",
-            "",
-            "import dagger.MapKey;",
-            "import dagger.multibindings.ClassKey;",
-            "",
-            "public class MapKeys {",
-            "  @MapKey(unwrapValue = false)",
-            "  public @interface ComplexKey {",
-            "    Class<?>[] manyClasses();",
-            "    Class<?> oneClass();",
-            "    ClassKey annotation();",
-            "  }",
-            "",
-            "  @MapKey",
-            "  @interface EnumKey {",
-            "    PackagePrivateEnum value();",
-            "  }",
-            "",
-            "  enum PackagePrivateEnum { INACCESSIBLE }",
-            "",
-            "  interface Inaccessible {}",
-            "}");
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "mapkeys.MapModule",
-            "package mapkeys;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ClassKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "public interface MapModule {",
-            "  @Provides @IntoMap @ClassKey(MapKeys.Inaccessible.class)",
-            "  static int classKey() { return 1; }",
-            "",
-            "  @Provides @IntoMap @MapKeys.EnumKey(MapKeys.PackagePrivateEnum.INACCESSIBLE)",
-            "  static int enumKey() { return 1; }",
-            "",
-            "  @Binds Object bindInaccessibleEnumMapToAccessibleTypeForComponent(",
-            "    Map<MapKeys.PackagePrivateEnum, Integer> map);",
-            "",
-            "  @Provides @IntoMap",
-            "  @MapKeys.ComplexKey(",
-            "    manyClasses = {java.lang.Object.class, java.lang.String.class},",
-            "    oneClass = MapKeys.Inaccessible.class,",
-            "    annotation = @ClassKey(java.lang.Object.class)",
-            "  )",
-            "  static int complexKeyWithInaccessibleValue() { return 1; }",
-            "",
-            "  @Provides @IntoMap",
-            "  @MapKeys.ComplexKey(",
-            "    manyClasses = {MapKeys.Inaccessible.class, java.lang.String.class},",
-            "    oneClass = java.lang.String.class,",
-            "    annotation = @ClassKey(java.lang.Object.class)",
-            "  )",
-            "  static int complexKeyWithInaccessibleArrayValue() { return 1; }",
-            "",
-            "  @Provides @IntoMap",
-            "  @MapKeys.ComplexKey(",
-            "    manyClasses = {java.lang.String.class},",
-            "    oneClass = java.lang.String.class,",
-            "    annotation = @ClassKey(MapKeys.Inaccessible.class)",
-            "  )",
-            "  static int complexKeyWithInaccessibleAnnotationValue() { return 1; }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "import mapkeys.MapKeys;",
-            "import mapkeys.MapModule;",
-            "",
-            "@Component(modules = MapModule.class)",
-            "interface TestComponent {",
-            "  Map<Class<?>, Integer> classKey();",
-            "  Provider<Map<Class<?>, Integer>> classKeyProvider();",
-            "",
-            "  Object inaccessibleEnum();",
-            "  Provider<Object> inaccessibleEnumProvider();",
-            "",
-            "  Map<MapKeys.ComplexKey, Integer> complexKey();",
-            "  Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(mapKeys, moduleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<Map<Class<?>, Integer>> mapOfClassOfAndIntegerProvider;",
-                "",
-                "  @SuppressWarnings(\"rawtypes\")",
-                "  private Provider mapOfPackagePrivateEnumAndIntegerProvider;",
-                "",
-                "  private Provider<Map<MapKeys.ComplexKey, Integer>>",
-                "      mapOfComplexKeyAndIntegerProvider;",
-                "",
-                "  private Map getMapOfPackagePrivateEnumAndInteger() {",
-                "    return ImmutableMap.of(",
-                "        MapModule_EnumKeyMapKey.create(), MapModule.enumKey());",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.mapOfClassOfAndIntegerProvider =",
-                "        MapFactory.<Class<?>, Integer>builder(1)",
-                "            .put(MapModule_ClassKeyMapKey.create(),",
-                "                 MapModule_ClassKeyFactory.create())",
-                "            .build();",
-                "    this.mapOfPackagePrivateEnumAndIntegerProvider =",
-                "        MapFactory.builder(1)",
-                "            .put(MapModule_EnumKeyMapKey.create(), ",
-                "                 (Provider) MapModule_EnumKeyFactory.create())",
-                "            .build();",
-                "    this.mapOfComplexKeyAndIntegerProvider =",
-                "       MapFactory.<MapKeys.ComplexKey, Integer>builder(3)",
-                "          .put(",
-                "             MapModule_ComplexKeyWithInaccessibleValueMapKey.create(),",
-                "             MapModule_ComplexKeyWithInaccessibleValueFactory.create())",
-                "          .put(",
-                "             MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(),",
-                "             MapModule_ComplexKeyWithInaccessibleArrayValueFactory.create())",
-                "          .put(",
-                "             MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(),",
-                "             MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory.create())",
-                "          .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Class<?>, Integer> classKey() {",
-                "    return ImmutableMap.<Class<?>, Integer>of(",
-                "        MapModule_ClassKeyMapKey.create(), MapModule.classKey());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<Class<?>, Integer>> classKeyProvider() {",
-                "    return mapOfClassOfAndIntegerProvider;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Object inaccessibleEnum() {",
-                "    return getMapOfPackagePrivateEnumAndInteger();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Object> inaccessibleEnumProvider() {",
-                "    return mapOfPackagePrivateEnumAndIntegerProvider;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<MapKeys.ComplexKey, Integer> complexKey() {",
-                "    return ImmutableMap.<MapKeys.ComplexKey, Integer>of(",
-                "        MapModule_ComplexKeyWithInaccessibleValueMapKey.create(),",
-                "        MapModule.complexKeyWithInaccessibleValue(),",
-                "        MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(),",
-                "        MapModule.complexKeyWithInaccessibleArrayValue(),",
-                "        MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(),",
-                "        MapModule.complexKeyWithInaccessibleAnnotationValue());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<MapKeys.ComplexKey, Integer>> complexKeyProvider() {",
-                "    return mapOfComplexKeyAndIntegerProvider;",
-                "  }",
-                "}"));
-    assertThat(compilation)
-        .generatedSourceFile(
-            "mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey",
-                "package mapkeys;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey {",
-                "  public static MapKeys.ComplexKey create() {",
-                "    return MapKeys_ComplexKeyCreator.createComplexKey(",
-                "        new Class[] {String.class},",
-                "        String.class,",
-                "        MapKeys_ComplexKeyCreator.createClassKey(MapKeys.Inaccessible.class));",
-                "  }",
-                "}"));
-    assertThat(compilation)
-        .generatedSourceFile("mapkeys.MapModule_ClassKeyMapKey")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "mapkeys.MapModule_ClassKeyMapKey",
-                "package mapkeys;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class MapModule_ClassKeyMapKey {",
-                "  public static Class<?> create() {",
-                "    return MapKeys.Inaccessible.class;",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void mapBindingsWithStringKey() {
-    JavaFileObject mapModuleOneFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleOne",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.StringKey;",
-                "import dagger.multibindings.IntoMap;",
-                "",
-                "@Module",
-                "final class MapModuleOne {",
-                "  @Provides @IntoMap @StringKey(\"Admin\") Handler provideAdminHandler() {",
-                "    return new AdminHandler();",
-                "  }",
-                "}");
-    JavaFileObject mapModuleTwoFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleTwo",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.IntoMap;",
-                "import dagger.multibindings.StringKey;",
-                "",
-                "@Module",
-                "final class MapModuleTwo {",
-                "  @Provides @IntoMap @StringKey(\"Login\") Handler provideLoginHandler() {",
-                "    return new LoginHandler();",
-                "  }",
-                "}");
-    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
-        "package test;",
-        "",
-        "interface Handler {}");
-    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
-        "package test;",
-        "",
-        "class LoginHandler implements Handler {",
-        "  public LoginHandler() {}",
-        "}");
-    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
-        "package test;",
-        "",
-        "class AdminHandler implements Handler {",
-        "  public AdminHandler() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
-        "interface TestComponent {",
-        "  Provider<Map<String, Provider<Handler>>> dispatcher();",
-        "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final MapModuleOne mapModuleOne;",
-                "  private final MapModuleTwo mapModuleTwo;",
-                "  private volatile Provider<Handler> provideAdminHandlerProvider;",
-                "  private volatile Provider<Handler> provideLoginHandlerProvider;",
-                "  private volatile Provider<Map<String, Provider<Handler>>>",
-                "      mapOfStringAndProviderOfHandlerProvider;",
-                "",
-                "  private Provider<Handler> getProvideAdminHandlerProvider() {",
-                "    Object local = provideAdminHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(1);",
-                "      provideAdminHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Provider<Handler> getProvideLoginHandlerProvider() {",
-                "    Object local = provideLoginHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      provideLoginHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Map<String, Provider<Handler>>",
-                "        getMapOfStringAndProviderOfHandler() {",
-                "    return ImmutableMap.<String, Provider<Handler>>of(",
-                "        \"Admin\", getProvideAdminHandlerProvider(),",
-                "        \"Login\", getProvideLoginHandlerProvider());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<String, Provider<Handler>>> dispatcher() {",
-                "    Object local = mapOfStringAndProviderOfHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      mapOfStringAndProviderOfHandlerProvider =",
-                "          (Provider<Map<String, Provider<Handler>>>) local;",
-                "    }",
-                "    return (Provider<Map<String, Provider<Handler>>>) local;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "            return (T) DaggerTestComponent.this",
-                "                 .getMapOfStringAndProviderOfHandler();",
-                "        case 1:",
-                "            return (T) MapModuleOne_ProvideAdminHandlerFactory",
-                "                .provideAdminHandler(DaggerTestComponent.this.mapModuleOne);",
-                "        case 2:",
-                "            return (T) MapModuleTwo_ProvideLoginHandlerFactory",
-                "                .provideLoginHandler(DaggerTestComponent.this.mapModuleTwo);",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<Handler> provideAdminHandlerProvider;",
-                "  private Provider<Handler> provideLoginHandlerProvider;",
-                "  private Provider<Map<String, Provider<Handler>>>",
-                "      mapOfStringAndProviderOfHandlerProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "      final MapModuleOne mapModuleOneParam,",
-                "      final MapModuleTwo mapModuleTwoParam) {",
-                "    this.provideAdminHandlerProvider =",
-                "        MapModuleOne_ProvideAdminHandlerFactory.create(mapModuleOneParam);",
-                "    this.provideLoginHandlerProvider =",
-                "        MapModuleTwo_ProvideLoginHandlerFactory.create(mapModuleTwoParam);",
-                "    this.mapOfStringAndProviderOfHandlerProvider =",
-                "        MapProviderFactory.<String, Handler>builder(2)",
-                "            .put(\"Admin\", provideAdminHandlerProvider)",
-                "            .put(\"Login\", provideLoginHandlerProvider)",
-                "            .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<String, Provider<Handler>>> dispatcher() {",
-                "    return mapOfStringAndProviderOfHandlerProvider;",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                mapModuleOneFile,
-                mapModuleTwoFile,
-                HandlerFile,
-                LoginHandlerFile,
-                AdminHandlerFile,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void mapBindingsWithWrappedKey() {
-    JavaFileObject mapModuleOneFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleOne",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.IntoMap;",
-                "",
-                "@Module",
-                "final class MapModuleOne {",
-                "  @Provides @IntoMap",
-                "  @WrappedClassKey(Integer.class) Handler provideAdminHandler() {",
-                "    return new AdminHandler();",
-                "  }",
-                "}");
-    JavaFileObject mapModuleTwoFile =
-        JavaFileObjects
-            .forSourceLines("test.MapModuleTwo",
-                "package test;",
-                "",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.IntoMap;",
-                "",
-                "@Module",
-                "final class MapModuleTwo {",
-                "  @Provides @IntoMap",
-                "  @WrappedClassKey(Long.class) Handler provideLoginHandler() {",
-                "    return new LoginHandler();",
-                "  }",
-                "}");
-    JavaFileObject wrappedClassKeyFile = JavaFileObjects.forSourceLines("test.WrappedClassKey",
-        "package test;",
-        "import dagger.MapKey;",
-        "import java.lang.annotation.Retention;",
-        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-        "",
-        "@MapKey(unwrapValue = false)",
-        "@Retention(RUNTIME)",
-        "public @interface WrappedClassKey {",
-        "  Class<?> value();",
-        "}");
-    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
-        "package test;",
-        "",
-        "interface Handler {}");
-    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
-        "package test;",
-        "",
-        "class LoginHandler implements Handler {",
-        "  public LoginHandler() {}",
-        "}");
-    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
-        "package test;",
-        "",
-        "class AdminHandler implements Handler {",
-        "  public AdminHandler() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
-        "interface TestComponent {",
-        "  Provider<Map<WrappedClassKey, Provider<Handler>>> dispatcher();",
-        "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final MapModuleOne mapModuleOne;",
-                "  private final MapModuleTwo mapModuleTwo;",
-                "  private volatile Provider<Handler> provideAdminHandlerProvider;",
-                "  private volatile Provider<Handler> provideLoginHandlerProvider;",
-                "  private volatile Provider<Map<WrappedClassKey, Provider<Handler>>>",
-                "      mapOfWrappedClassKeyAndProviderOfHandlerProvider;",
-                "",
-                "  private DaggerTestComponent(",
-                "      MapModuleOne mapModuleOneParam,",
-                "      MapModuleTwo mapModuleTwoParam) {",
-                "    this.mapModuleOne = mapModuleOneParam;",
-                "    this.mapModuleTwo = mapModuleTwoParam;",
-                "  }",
-                "",
-                "  private Provider<Handler> getProvideAdminHandlerProvider() {",
-                "    Object local = provideAdminHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(1);",
-                "      provideAdminHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Provider<Handler> getProvideLoginHandlerProvider() {",
-                "    Object local = provideLoginHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      provideLoginHandlerProvider = (Provider<Handler>) local;",
-                "    }",
-                "    return (Provider<Handler>) local;",
-                "  }",
-                "",
-                "  private Map<WrappedClassKey, Provider<Handler>>",
-                "      getMapOfWrappedClassKeyAndProviderOfHandler() {",
-                "    return ImmutableMap.<WrappedClassKey, Provider<Handler>>of(",
-                "        WrappedClassKeyCreator.createWrappedClassKey(Integer.class),",
-                "        getProvideAdminHandlerProvider(),",
-                "        WrappedClassKeyCreator.createWrappedClassKey(Long.class),",
-                "        getProvideLoginHandlerProvider());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<WrappedClassKey, Provider<Handler>>> dispatcher() {",
-                "    Object local = mapOfWrappedClassKeyAndProviderOfHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      mapOfWrappedClassKeyAndProviderOfHandlerProvider =",
-                "          (Provider<Map<WrappedClassKey, Provider<Handler>>>) local;",
-                "    }",
-                "    return (Provider<Map<WrappedClassKey, Provider<Handler>>>) local;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "            return (T) DaggerTestComponent.this",
-                "                 .getMapOfWrappedClassKeyAndProviderOfHandler();",
-                "        case 1:",
-                "            return (T) MapModuleOne_ProvideAdminHandlerFactory",
-                "                .provideAdminHandler(DaggerTestComponent.this.mapModuleOne);",
-                "        case 2:",
-                "            return (T) MapModuleTwo_ProvideLoginHandlerFactory",
-                "                .provideLoginHandler(DaggerTestComponent.this.mapModuleTwo);",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<Handler> provideAdminHandlerProvider;",
-                "  private Provider<Handler> provideLoginHandlerProvider;",
-                "  private Provider<Map<WrappedClassKey, Provider<Handler>>>",
-                "      mapOfWrappedClassKeyAndProviderOfHandlerProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "      final MapModuleOne mapModuleOneParam,",
-                "      final MapModuleTwo mapModuleTwoParam) {",
-                "    this.provideAdminHandlerProvider =",
-                "        MapModuleOne_ProvideAdminHandlerFactory.create(mapModuleOneParam);",
-                "    this.provideLoginHandlerProvider =",
-                "        MapModuleTwo_ProvideLoginHandlerFactory.create(mapModuleTwoParam);",
-                "    this.mapOfWrappedClassKeyAndProviderOfHandlerProvider =",
-                "        MapProviderFactory.<WrappedClassKey, Handler>builder(2)",
-                "            .put(WrappedClassKeyCreator.createWrappedClassKey(Integer.class),",
-                "                provideAdminHandlerProvider)",
-                "            .put(WrappedClassKeyCreator.createWrappedClassKey(Long.class),",
-                "                provideLoginHandlerProvider)",
-                "            .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<WrappedClassKey, Provider<Handler>>> dispatcher() {",
-                "    return mapOfWrappedClassKeyAndProviderOfHandlerProvider;",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                mapModuleOneFile,
-                mapModuleTwoFile,
-                wrappedClassKeyFile,
-                HandlerFile,
-                LoginHandlerFile,
-                AdminHandlerFile,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void mapBindingsWithNonProviderValue() {
-    JavaFileObject mapModuleOneFile = JavaFileObjects.forSourceLines("test.MapModuleOne",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoMap;",
-        "",
-        "@Module",
-        "final class MapModuleOne {",
-        "  @Provides @IntoMap @PathKey(PathEnum.ADMIN) Handler provideAdminHandler() {",
-        "    return new AdminHandler();",
-        "  }",
-        "}");
-    JavaFileObject mapModuleTwoFile = JavaFileObjects.forSourceLines("test.MapModuleTwo",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoMap;",
-        "",
-        "@Module",
-        "final class MapModuleTwo {",
-        "  @Provides @IntoMap @PathKey(PathEnum.LOGIN) Handler provideLoginHandler() {",
-        "    return new LoginHandler();",
-        "  }",
-        "}");
-    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
-        "package test;",
-        "import dagger.MapKey;",
-        "import java.lang.annotation.Retention;",
-        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-        "",
-        "@MapKey(unwrapValue = true)",
-        "@Retention(RUNTIME)",
-        "public @interface PathKey {",
-        "  PathEnum value();",
-        "}");
-    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
-        "package test;",
-        "",
-        "public enum PathEnum {",
-        "    ADMIN,",
-        "    LOGIN;",
-        "}");
-    JavaFileObject HandlerFile = JavaFileObjects.forSourceLines("test.Handler",
-        "package test;",
-        "",
-        "interface Handler {}");
-    JavaFileObject LoginHandlerFile = JavaFileObjects.forSourceLines("test.LoginHandler",
-        "package test;",
-        "",
-        "class LoginHandler implements Handler {",
-        "  public LoginHandler() {}",
-        "}");
-    JavaFileObject AdminHandlerFile = JavaFileObjects.forSourceLines("test.AdminHandler",
-        "package test;",
-        "",
-        "class AdminHandler implements Handler {",
-        "  public AdminHandler() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {MapModuleOne.class, MapModuleTwo.class})",
-        "interface TestComponent {",
-        "  Provider<Map<PathEnum, Handler>> dispatcher();",
-        "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final MapModuleOne mapModuleOne;",
-                "  private final MapModuleTwo mapModuleTwo;",
-                "  private volatile Provider<Map<PathEnum, Handler>>",
-                "      mapOfPathEnumAndHandlerProvider;",
-                "",
-                "  private Map<PathEnum, Handler> getMapOfPathEnumAndHandler() {",
-                "    return ImmutableMap.<PathEnum, Handler>of(",
-                "        PathEnum.ADMIN,",
-                "        MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(",
-                "            mapModuleOne),",
-                "        PathEnum.LOGIN,",
-                "        MapModuleTwo_ProvideLoginHandlerFactory.provideLoginHandler(",
-                "            mapModuleTwo));",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<PathEnum, Handler>> dispatcher() {",
-                "    Object local = mapOfPathEnumAndHandlerProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      mapOfPathEnumAndHandlerProvider = (Provider<Map<PathEnum, Handler>>) local;",
-                "    }",
-                "    return (Provider<Map<PathEnum, Handler>>) local;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) DaggerTestComponent.this.getMapOfPathEnumAndHandler();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<Handler> provideAdminHandlerProvider;",
-                "  private Provider<Handler> provideLoginHandlerProvider;",
-                "  private Provider<Map<PathEnum, Handler>> mapOfPathEnumAndHandlerProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "        final MapModuleOne mapModuleOneParam,",
-                "        final MapModuleTwo mapModuleTwoParam) {",
-                "    this.provideAdminHandlerProvider =",
-                "        MapModuleOne_ProvideAdminHandlerFactory.create(mapModuleOneParam);",
-                "    this.provideLoginHandlerProvider =",
-                "        MapModuleTwo_ProvideLoginHandlerFactory.create(mapModuleTwoParam);",
-                "    this.mapOfPathEnumAndHandlerProvider =",
-                "        MapFactory.<PathEnum, Handler>builder(2)",
-                "            .put(PathEnum.ADMIN, provideAdminHandlerProvider)",
-                "            .put(PathEnum.LOGIN, provideLoginHandlerProvider)",
-                "            .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<PathEnum, Handler>> dispatcher() {",
-                "    return mapOfPathEnumAndHandlerProvider;",
-                "  }",
-                "}");
-    }
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                mapModuleOneFile,
-                mapModuleTwoFile,
-                enumKeyFile,
-                pathEnumFile,
-                HandlerFile,
-                LoginHandlerFile,
-                AdminHandlerFile,
-                componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void injectMapWithoutMapBinding() {
-    JavaFileObject mapModuleFile = JavaFileObjects.forSourceLines("test.MapModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import java.util.HashMap;",
-        "import java.util.Map;",
-        "",
-        "@Module",
-        "final class MapModule {",
-        "  @Provides Map<String, String> provideAMap() {",
-        "    Map<String, String> map = new HashMap<String, String>();",
-        "    map.put(\"Hello\", \"World\");",
-        "    return map;",
-        "  }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "",
-        "@Component(modules = {MapModule.class})",
-        "interface TestComponent {",
-        "  Map<String, String> dispatcher();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private final MapModule mapModule;",
-            "",
-            "  @Override",
-            "  public Map<String, String> dispatcher() {",
-            "    return MapModule_ProvideAMapFactory.provideAMap(mapModule);",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(mapModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MapBindingExpressionTest.java b/javatests/dagger/internal/codegen/MapBindingExpressionTest.java
deleted file mode 100644
index 11f6bc1..0000000
--- a/javatests/dagger/internal/codegen/MapBindingExpressionTest.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.CLASS_PATH_WITHOUT_GUAVA_OPTION;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.Compiler;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MapBindingExpressionTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public MapBindingExpressionTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void mapBindings() {
-    JavaFileObject mapModuleFile = JavaFileObjects.forSourceLines("test.MapModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntKey;",
-        "import dagger.multibindings.IntoMap;",
-        "import dagger.multibindings.LongKey;",
-        "import dagger.multibindings.Multibinds;",
-        "import java.util.Map;",
-        "",
-        "@Module",
-        "interface MapModule {",
-        "  @Multibinds Map<String, String> stringMap();",
-        "  @Provides @IntoMap @IntKey(0) static int provideInt() { return 0; }",
-        "  @Provides @IntoMap @LongKey(0) static long provideLong0() { return 0; }",
-        "  @Provides @IntoMap @LongKey(1) static long provideLong1() { return 1; }",
-        "  @Provides @IntoMap @LongKey(2) static long provideLong2() { return 2; }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Map;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = MapModule.class)",
-        "interface TestComponent {",
-        "  Map<String, String> strings();",
-        "  Map<String, Provider<String>> providerStrings();",
-        "",
-        "  Map<Integer, Integer> ints();",
-        "  Map<Integer, Provider<Integer>> providerInts();",
-        "  Map<Long, Long> longs();",
-        "  Map<Long, Provider<Long>> providerLongs();",
-        "}");
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.internal.MapBuilder;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Provider<Integer> provideIntProvider;",
-                "  private volatile Provider<Long> provideLong0Provider;",
-                "  private volatile Provider<Long> provideLong1Provider;",
-                "  private volatile Provider<Long> provideLong2Provider;",
-                "",
-                "  private Provider<Integer> getProvideIntProvider() {",
-                "    Object local = provideIntProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      provideIntProvider = (Provider<Integer>) local;",
-                "    }",
-                "    return (Provider<Integer>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong0Provider() {",
-                "    Object local = provideLong0Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(1);",
-                "      provideLong0Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong1Provider() {",
-                "    Object local = provideLong1Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      provideLong1Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong2Provider() {",
-                "    Object local = provideLong2Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(3);",
-                "      provideLong2Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }")
-            .addLines(
-                "  @Override",
-                "  public Map<String, String> strings() {",
-                "    return Collections.<String, String>emptyMap();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<String, Provider<String>> providerStrings() {",
-                "    return Collections.<String, Provider<String>>emptyMap();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Integer, Integer> ints() {",
-                "    return Collections.<Integer, Integer>singletonMap(0, MapModule.provideInt());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Integer, Provider<Integer>> providerInts() {",
-                "    return Collections.<Integer, Provider<Integer>>singletonMap(")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "        0, MapModule_ProvideIntFactory.create());")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "        0, getProvideIntProvider());")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Long, Long> longs() {",
-                "    return MapBuilder.<Long, Long>newMapBuilder(3)",
-                "        .put(0L, MapModule.provideLong0())",
-                "        .put(1L, MapModule.provideLong1())",
-                "        .put(2L, MapModule.provideLong2())",
-                "        .build();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Long, Provider<Long>> providerLongs() {",
-                "    return MapBuilder.<Long, Provider<Long>>newMapBuilder(3)")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "        .put(0L, MapModule_ProvideLong0Factory.create())",
-                "        .put(1L, MapModule_ProvideLong1Factory.create())",
-                "        .put(2L, MapModule_ProvideLong2Factory.create())")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "        .put(0L, getProvideLong0Provider())",
-                "        .put(1L, getProvideLong1Provider())",
-                "        .put(2L, getProvideLong2Provider())")
-            .addLines( //
-                "        .build();", "  }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) (Integer) MapModule.provideInt();",
-                "        case 1: return (T) (Long) MapModule.provideLong0();",
-                "        case 2: return (T) (Long) MapModule.provideLong1();",
-                "        case 3: return (T) (Long) MapModule.provideLong2();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}")
-            .build();
-    Compilation compilation = daggerCompilerWithoutGuava().compile(mapModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void inaccessible() {
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible",
-            "package other;",
-            "",
-            "class Inaccessible {}");
-    JavaFileObject usesInaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessible",
-            "package other;",
-            "",
-            "import java.util.Map;",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessible {",
-            "  @Inject UsesInaccessible(Map<Integer, Inaccessible> map) {}",
-            "}");
-
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.TestModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "public abstract class TestModule {",
-            "  @Multibinds abstract Map<Integer, Inaccessible> ints();",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "import other.TestModule;",
-            "import other.UsesInaccessible;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  UsesInaccessible usesInaccessible();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import other.UsesInaccessible;",
-            "import other.UsesInaccessible_Factory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public UsesInaccessible usesInaccessible() {",
-            "    return UsesInaccessible_Factory.newInstance(",
-            "        (Map) Collections.emptyMap());",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompilerWithoutGuava().compile(module, inaccessible, usesInaccessible, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void subcomponentOmitsInheritedBindings() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides @IntoMap @StringKey(\"parent key\") Object parentKeyObject() {",
-            "    return \"parent value\";",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  Map<String, Object> objectMap();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private final ParentModule parentModule;",
-            "",
-            "  private final class ChildImpl implements Child {",
-            "    @Override",
-            "    public Map<String, Object> objectMap() {",
-            "      return Collections.<String, Object>singletonMap(",
-            "          \"parent key\",",
-            "          ParentModule_ParentKeyObjectFactory.parentKeyObject(",
-            "              DaggerParent.this.parentModule));",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompilerWithoutGuava().compile(parent, parentModule, child);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  private Compiler daggerCompilerWithoutGuava() {
-    return daggerCompiler()
-        .withOptions(compilerMode.javacopts().append(CLASS_PATH_WITHOUT_GUAVA_OPTION));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MapBindingExpressionWithGuavaTest.java b/javatests/dagger/internal/codegen/MapBindingExpressionWithGuavaTest.java
deleted file mode 100644
index aa1a715..0000000
--- a/javatests/dagger/internal/codegen/MapBindingExpressionWithGuavaTest.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.compilerWithOptions;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MapBindingExpressionWithGuavaTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public MapBindingExpressionWithGuavaTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void mapBindings() {
-    JavaFileObject mapModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.MapModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.LongKey;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "interface MapModule {",
-            "  @Multibinds Map<String, String> stringMap();",
-            "  @Provides @IntoMap @IntKey(0) static int provideInt() { return 0; }",
-            "  @Provides @IntoMap @LongKey(0) static long provideLong0() { return 0; }",
-            "  @Provides @IntoMap @LongKey(1) static long provideLong1() { return 1; }",
-            "  @Provides @IntoMap @LongKey(2) static long provideLong2() { return 2; }",
-            "}");
-    JavaFileObject subcomponentModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.SubcomponentMapModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.LongKey;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "interface SubcomponentMapModule {",
-            "  @Provides @IntoMap @LongKey(3) static long provideLong3() { return 3; }",
-            "  @Provides @IntoMap @LongKey(4) static long provideLong4() { return 4; }",
-            "  @Provides @IntoMap @LongKey(5) static long provideLong5() { return 5; }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = MapModule.class)",
-            "interface TestComponent {",
-            "  Map<String, String> strings();",
-            "  Map<String, Provider<String>> providerStrings();",
-            "",
-            "  Map<Integer, Integer> ints();",
-            "  Map<Integer, Provider<Integer>> providerInts();",
-            "  Map<Long, Long> longs();",
-            "  Map<Long, Provider<Long>> providerLongs();",
-            "",
-            "  Sub sub();",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Subcomponent(modules = SubcomponentMapModule.class)",
-            "interface Sub {",
-            "  Map<Long, Long> longs();",
-            "  Map<Long, Provider<Long>> providerLongs();",
-            "}");
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Provider<Integer> provideIntProvider;",
-                "  private volatile Provider<Long> provideLong0Provider;",
-                "  private volatile Provider<Long> provideLong1Provider;",
-                "  private volatile Provider<Long> provideLong2Provider;",
-                "",
-                "  private Provider<Integer> getProvideIntProvider() {",
-                "    Object local = provideIntProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      provideIntProvider = (Provider<Integer>) local;",
-                "    }",
-                "    return (Provider<Integer>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong0Provider() {",
-                "    Object local = provideLong0Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(1);",
-                "      provideLong0Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong1Provider() {",
-                "    Object local = provideLong1Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      provideLong1Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }",
-                "",
-                "  private Provider<Long> getProvideLong2Provider() {",
-                "    Object local = provideLong2Provider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(3);",
-                "      provideLong2Provider = (Provider<Long>) local;",
-                "    }",
-                "    return (Provider<Long>) local;",
-                "  }")
-            .addLines(
-                "  @Override",
-                "  public Map<String, String> strings() {",
-                "    return ImmutableMap.<String, String>of();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<String, Provider<String>> providerStrings() {",
-                "    return ImmutableMap.<String, Provider<String>>of();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Integer, Integer> ints() {",
-                "    return ImmutableMap.<Integer, Integer>of(0, MapModule.provideInt());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Integer, Provider<Integer>> providerInts() {",
-                "    return ImmutableMap.<Integer, Provider<Integer>>of(")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "        0, MapModule_ProvideIntFactory.create());")
-            .addLinesIn(
-                FAST_INIT_MODE, //
-                "        0, getProvideIntProvider());")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Long, Long> longs() {",
-                "    return ImmutableMap.<Long, Long>of(",
-                "      0L, MapModule.provideLong0(),",
-                "      1L, MapModule.provideLong1(),",
-                "      2L, MapModule.provideLong2());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Map<Long, Provider<Long>> providerLongs() {",
-                "    return ImmutableMap.<Long, Provider<Long>>of(")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "      0L, MapModule_ProvideLong0Factory.create(),",
-                "      1L, MapModule_ProvideLong1Factory.create(),",
-                "      2L, MapModule_ProvideLong2Factory.create());")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "      0L, getProvideLong0Provider(),",
-                "      1L, getProvideLong1Provider(),",
-                "      2L, getProvideLong2Provider());")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Sub sub() {",
-                "    return new SubImpl();",
-                "  }",
-                "",
-                "  private final class SubImpl implements Sub {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    private volatile Provider<Long> provideLong3Provider;",
-                "    private volatile Provider<Long> provideLong4Provider;",
-                "    private volatile Provider<Long> provideLong5Provider;",
-                "    private SubImpl() {}",
-                "",
-                "    private Provider<Long> getProvideLong3Provider() {",
-                "      Object local = provideLong3Provider;",
-                "      if (local == null) {",
-                "        local = new SwitchingProvider<>(0);",
-                "        provideLong3Provider = (Provider<Long>) local;",
-                "      }",
-                "      return (Provider<Long>) local;",
-                "    }",
-                "",
-                "    private Provider<Long> getProvideLong4Provider() {",
-                "      Object local = provideLong4Provider;",
-                "      if (local == null) {",
-                "        local = new SwitchingProvider<>(1);",
-                "        provideLong4Provider = (Provider<Long>) local;",
-                "      }",
-                "      return (Provider<Long>) local;",
-                "    }",
-                "",
-                "    private Provider<Long> getProvideLong5Provider() {",
-                "      Object local = provideLong5Provider;",
-                "      if (local == null) {",
-                "        local = new SwitchingProvider<>(2);",
-                "        provideLong5Provider = (Provider<Long>) local;",
-                "      }",
-                "      return (Provider<Long>) local;",
-                "    }")
-            .addLines(
-                "    @Override",
-                "    public Map<Long, Long> longs() {",
-                "      return ImmutableMap.<Long, Long>builderWithExpectedSize(6)",
-                "          .put(0L, MapModule.provideLong0())",
-                "          .put(1L, MapModule.provideLong1())",
-                "          .put(2L, MapModule.provideLong2())",
-                "          .put(3L, SubcomponentMapModule.provideLong3())",
-                "          .put(4L, SubcomponentMapModule.provideLong4())",
-                "          .put(5L, SubcomponentMapModule.provideLong5())",
-                "          .build();",
-                "    }",
-                "",
-                "    @Override",
-                "    public Map<Long, Provider<Long>> providerLongs() {",
-                "      return ImmutableMap.<Long, Provider<Long>>builderWithExpectedSize(6)")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "          .put(0L, MapModule_ProvideLong0Factory.create())",
-                "          .put(1L, MapModule_ProvideLong1Factory.create())",
-                "          .put(2L, MapModule_ProvideLong2Factory.create())",
-                "          .put(3L, SubcomponentMapModule_ProvideLong3Factory.create())",
-                "          .put(4L, SubcomponentMapModule_ProvideLong4Factory.create())",
-                "          .put(5L, SubcomponentMapModule_ProvideLong5Factory.create())")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "          .put(0L, DaggerTestComponent.this.getProvideLong0Provider())",
-                "          .put(1L, DaggerTestComponent.this.getProvideLong1Provider())",
-                "          .put(2L, DaggerTestComponent.this.getProvideLong2Provider())",
-                "          .put(3L, getProvideLong3Provider())",
-                "          .put(4L, getProvideLong4Provider())",
-                "          .put(5L, getProvideLong5Provider())")
-            .addLines( //
-                "          .build();", "    }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    private final class SwitchingProvider<T> implements Provider<T> {",
-                "      private final int id;",
-                "",
-                "      SwitchingProvider(int id) {",
-                "        this.id = id;",
-                "      }",
-                "",
-                "      @SuppressWarnings(\"unchecked\")",
-                "      @Override",
-                "      public T get() {",
-                "        switch (id) {",
-                "          case 0: return (T) (Long) SubcomponentMapModule.provideLong3();",
-                "          case 1: return (T) (Long) SubcomponentMapModule.provideLong4();",
-                "          case 2: return (T) (Long) SubcomponentMapModule.provideLong5();",
-                "          default: throw new AssertionError(id);",
-                "        }",
-                "      }",
-                "    }",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) (Integer) MapModule.provideInt();",
-                "        case 1: return (T) (Long) MapModule.provideLong0();",
-                "        case 2: return (T) (Long) MapModule.provideLong1();",
-                "        case 3: return (T) (Long) MapModule.provideLong2();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}")
-            .build();
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(mapModuleFile, componentFile, subcomponentModuleFile, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void inaccessible() {
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible", "package other;", "", "class Inaccessible {}");
-    JavaFileObject usesInaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessible",
-            "package other;",
-            "",
-            "import java.util.Map;",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessible {",
-            "  @Inject UsesInaccessible(Map<Integer, Inaccessible> map) {}",
-            "}");
-
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.TestModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "public abstract class TestModule {",
-            "  @Multibinds abstract Map<Integer, Inaccessible> ints();",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "import other.TestModule;",
-            "import other.UsesInaccessible;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  UsesInaccessible usesInaccessible();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import other.UsesInaccessible;",
-            "import other.UsesInaccessible_Factory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public UsesInaccessible usesInaccessible() {",
-            "    return UsesInaccessible_Factory.newInstance((Map) ImmutableMap.of());",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, inaccessible, usesInaccessible, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void subcomponentOmitsInheritedBindings() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides @IntoMap @StringKey(\"parent key\") Object parentKeyObject() {",
-            "    return \"parent value\";",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Map;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  Map<String, Object> objectMap();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private final ParentModule parentModule;",
-            "",
-            "  private final class ChildImpl implements Child {",
-            "    @Override",
-            "    public Map<String, Object> objectMap() {",
-            "      return ImmutableMap.<String, Object>of(",
-            "          \"parent key\",",
-            "          ParentModule_ParentKeyObjectFactory.parentKeyObject(",
-            "              DaggerParent.this.parentModule));",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent, parentModule, child);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void productionComponents() {
-    JavaFileObject mapModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.MapModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Map;",
-            "",
-            "@Module",
-            "interface MapModule {",
-            "  @Multibinds Map<String, String> stringMap();",
-            "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import dagger.producers.ProductionComponent;",
-        "import java.util.Map;",
-        "",
-        "@ProductionComponent(modules = MapModule.class)",
-        "interface TestComponent {",
-        "  ListenableFuture<Map<String, String>> stringMap();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import dagger.producers.internal.CancellationListener;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent, "
-                + "CancellationListener {",
-            "  @Override",
-            "  public ListenableFuture<Map<String, String>> stringMap() {",
-            "    return Futures.immediateFuture(",
-            "        (Map<String, String>) ImmutableMap.<String, String>of());",
-            "  }",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {}",
-            "}");
-    Compilation compilation =
-        compilerWithOptions(
-                compilerMode
-                , CompilerMode.JAVA7
-                )
-            .compile(mapModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MapKeyProcessorTest.java b/javatests/dagger/internal/codegen/MapKeyProcessorTest.java
deleted file mode 100644
index 746c60d..0000000
--- a/javatests/dagger/internal/codegen/MapKeyProcessorTest.java
+++ /dev/null
@@ -1,144 +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.truth.Truth.assertAbout;
-import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.auto.value.processor.AutoAnnotationProcessor;
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MapKeyProcessorTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public MapKeyProcessorTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void mapKeyCreatorFile() {
-    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.PathKey",
-        "package test;",
-        "import dagger.MapKey;",
-        "import java.lang.annotation.Retention;",
-        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-        "",
-        "@MapKey(unwrapValue = false)",
-        "@Retention(RUNTIME)",
-        "public @interface PathKey {",
-        "  PathEnum value();",
-        "  String relativePath() default \"Defaultpath\";",
-        "}");
-    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
-        "package test;",
-        "",
-        "public enum PathEnum {",
-        "    ADMIN,",
-        "    LOGIN;",
-        "}");
-    JavaFileObject generatedKeyCreator =
-        JavaFileObjects.forSourceLines(
-            "test.PathKeyCreator",
-            "package test;",
-            "",
-            "import com.google.auto.value.AutoAnnotation;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class PathKeyCreator {",
-            "  private PathKeyCreator() {}",
-            "",
-            "  @AutoAnnotation",
-            "  public static PathKey createPathKey(PathEnum value, String relativePath) {",
-            "    return new AutoAnnotation_PathKeyCreator_createPathKey(value, relativePath);",
-            "  }",
-            "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(enumKeyFile, pathEnumFile))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(generatedKeyCreator);
-  }
-
-  @Test
-  public void nestedMapKeyCreatorFile() {
-    JavaFileObject enumKeyFile = JavaFileObjects.forSourceLines("test.Container",
-        "package test;",
-        "import dagger.MapKey;",
-        "import java.lang.annotation.Retention;",
-        "import static java.lang.annotation.RetentionPolicy.RUNTIME;",
-        "",
-        "public interface Container {",
-        "@MapKey(unwrapValue = false)",
-        "@Retention(RUNTIME)",
-        "public @interface PathKey {",
-        "  PathEnum value();",
-        "  String relativePath() default \"Defaultpath\";",
-        "}",
-        "}");
-    JavaFileObject pathEnumFile = JavaFileObjects.forSourceLines("test.PathEnum",
-        "package test;",
-        "",
-        "public enum PathEnum {",
-        "    ADMIN,",
-        "    LOGIN;",
-        "}");
-    JavaFileObject generatedKeyCreator =
-        JavaFileObjects.forSourceLines(
-            "test.Container_PathKeyCreator",
-            "package test;",
-            "",
-            "import com.google.auto.value.AutoAnnotation;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class Container_PathKeyCreator {",
-            "  private Container_PathKeyCreator() {}",
-            "",
-            "  @AutoAnnotation",
-            "  public static Container.PathKey createPathKey("
-                + "PathEnum value, String relativePath) {",
-            "    return new AutoAnnotation_Container_PathKeyCreator_createPathKey(",
-            "        value, relativePath);",
-            "  }",
-            "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(enumKeyFile, pathEnumFile))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(generatedKeyCreator);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java b/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java
deleted file mode 100644
index 04b0986..0000000
--- a/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java
+++ /dev/null
@@ -1,332 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MapMultibindingValidationTest {
-  @Test
-  public void duplicateMapKeys() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.MapModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.StringKey;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "final class MapModule {",
-            "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKey() {",
-            "    return \"one\";",
-            "  }",
-            "",
-            "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKeyAgain() {",
-            "    return \"one again\";",
-            "  }",
-            "}");
-
-    // If they're all there, report only Map<K, V>.
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                component(
-                    "Map<String, Object> objects();",
-                    "Map<String, Provider<Object>> objectProviders();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,java.lang.Object>");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKey()");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKeyAgain()");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler().withOptions("-Adagger.fullBindingGraphValidation=ERROR").compile(module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>")
-        .inFile(module)
-        .onLineContaining("class MapModule");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKey()");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKeyAgain()");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, V> and Map<K, Provider<V>>, report only Map<K, V>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                component(
-                    "Map<String, Object> objects();",
-                    "Map<String, Provider<Object>> objectProviders();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,java.lang.Object>");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, V> and Map<K, Producer<V>>, report only Map<K, V>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                component(
-                    "Map<String, Object> objects();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,java.lang.Object>");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, Provider<V>> and Map<K, Producer<V>>, report only Map<K, Provider<V>>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                component(
-                    "Map<String, Provider<Object>> objectProviders();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation = daggerCompiler().compile(module, component("Map<String, Object> objects();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,java.lang.Object>");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .compile(module, component("Map<String, Provider<Object>> objectProviders();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .compile(
-                module, component("Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "The same map key is bound more than once for "
-                + "java.util.Map<java.lang.String,dagger.producers.Producer<java.lang.Object>>");
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void inconsistentMapKeyAnnotations() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.MapModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.StringKey;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "final class MapModule {",
-            "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKey() {",
-            "    return \"one\";",
-            "  }",
-            "",
-            "  @Provides @IntoMap @StringKeyTwo(\"BKey\") Object provideObjectForBKey() {",
-            "    return \"two\";",
-            "  }",
-            "}");
-    JavaFileObject stringKeyTwoFile =
-        JavaFileObjects.forSourceLines(
-            "test.StringKeyTwo",
-            "package test;",
-            "",
-            "import dagger.MapKey;",
-            "",
-            "@MapKey(unwrapValue = true)",
-            "public @interface StringKeyTwo {",
-            "  String value();",
-            "}");
-
-    // If they're all there, report only Map<K, V>.
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component(
-                    "Map<String, Object> objects();",
-                    "Map<String, Provider<Object>> objectProviders();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,java.lang.Object>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKey()");
-    assertThat(compilation).hadErrorContaining("provideObjectForBKey()");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(module, stringKeyTwoFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>"
-                + " uses more than one @MapKey annotation type")
-        .inFile(module)
-        .onLineContaining("class MapModule");
-    assertThat(compilation).hadErrorContaining("provideObjectForAKey()");
-    assertThat(compilation).hadErrorContaining("provideObjectForBKey()");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, V> and Map<K, Provider<V>>, report only Map<K, V>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component(
-                    "Map<String, Object> objects();",
-                    "Map<String, Provider<Object>> objectProviders();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,java.lang.Object>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, V> and Map<K, Producer<V>>, report only Map<K, V>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component(
-                    "Map<String, Object> objects();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,java.lang.Object>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-
-    // If there's Map<K, Provider<V>> and Map<K, Producer<V>>, report only Map<K, Provider<V>>.
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component(
-                    "Map<String, Provider<Object>> objectProviders();",
-                    "Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .compile(module, stringKeyTwoFile, component("Map<String, Object> objects();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,java.lang.Object>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component("Map<String, Provider<Object>> objectProviders();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,javax.inject.Provider<java.lang.Object>>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-
-    compilation =
-        daggerCompiler()
-            .compile(
-                module,
-                stringKeyTwoFile,
-                component("Producer<Map<String, Producer<Object>>> objectProducers();"));
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,dagger.producers.Producer<java.lang.Object>>"
-                + " uses more than one @MapKey annotation type");
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  private static JavaFileObject component(String... entryPoints) {
-    return JavaFileObjects.forSourceLines(
-        "test.TestComponent",
-        ImmutableList.<String>builder()
-            .add(
-                "package test;",
-                "",
-                "import dagger.Component;",
-                "import dagger.producers.Producer;",
-                "import java.util.Map;",
-                "import javax.inject.Provider;",
-                "",
-                "@Component(modules = {MapModule.class})",
-                "interface TestComponent {")
-            .add(entryPoints)
-            .add("}")
-            .build());
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MembersInjectionTest.java b/javatests/dagger/internal/codegen/MembersInjectionTest.java
deleted file mode 100644
index edaedaf..0000000
--- a/javatests/dagger/internal/codegen/MembersInjectionTest.java
+++ /dev/null
@@ -1,1531 +0,0 @@
-/*
- * Copyright (C) 2015 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.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
-import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.TypeElement;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MembersInjectionTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public MembersInjectionTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void parentClass_noInjectedMembers() {
-    JavaFileObject childFile = JavaFileObjects.forSourceLines("test.Child",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "public final class Child extends Parent {",
-        "  @Inject Child() {}",
-        "}");
-    JavaFileObject parentFile = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "public abstract class Parent {}");
-
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  Child child();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public Child child() {",
-            "    return new Child();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(childFile, parentFile, componentFile);
-
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void parentClass_injectedMembersInSupertype() {
-    JavaFileObject childFile = JavaFileObjects.forSourceLines("test.Child",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "public final class Child extends Parent {",
-        "  @Inject Child() {}",
-        "}");
-    JavaFileObject parentFile = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "public abstract class Parent {",
-        "  @Inject Dep dep;",
-        "}");
-    JavaFileObject depFile = JavaFileObjects.forSourceLines("test.Dep",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class Dep {",
-        "  @Inject Dep() {}",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  Child child();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public Child child() {",
-            "    return injectChild(Child_Factory.newInstance());",
-            "  }",
-            "",
-            "  @CanIgnoreReturnValue",
-            "  private Child injectChild(Child instance) {",
-            "    Parent_MembersInjector.injectDep(instance, new Dep());",
-            "    return instance;",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(childFile, parentFile, depFile, componentFile);
-
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test public void fieldAndMethodGenerics() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class GenericClass<A, B> {",
-        "  @Inject A a;",
-        "",
-        "  @Inject GenericClass() {}",
-        "",
-        " @Inject void register(B b) {}",
-        "}");
-    JavaFileObject expected = JavaFileObjects.forSourceLines(
-        "test.GenericClass_MembersInjector",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        IMPORT_GENERATED_ANNOTATION,
-        "import javax.inject.Provider;",
-        "",
-        GENERATED_ANNOTATION,
-        "public final class GenericClass_MembersInjector<A, B>",
-        "    implements MembersInjector<GenericClass<A, B>> {",
-        "  private final Provider<A> aProvider;",
-        "  private final Provider<B> bProvider;",
-        "",
-        "  public GenericClass_MembersInjector(Provider<A> aProvider, Provider<B> bProvider) {",
-        "    this.aProvider = aProvider;",
-        "    this.bProvider = bProvider;",
-        "  }",
-        "",
-        "  public static <A, B> MembersInjector<GenericClass<A, B>> create(",
-        "      Provider<A> aProvider, Provider<B> bProvider) {",
-        "    return new GenericClass_MembersInjector<A, B>(aProvider, bProvider);",
-        "  }",
-        "",
-        "  @Override",
-        "  public void injectMembers(GenericClass<A, B> instance) {",
-        "    injectA(instance, aProvider.get());",
-        "    injectRegister(instance, bProvider.get());",
-        "  }",
-        "",
-        "  public static <A, B> void injectA(Object instance, A a) {",
-        "    ((GenericClass<A, B>) instance).a = a;",
-        "  }",
-        "",
-        "  public static <A, B> void injectRegister(Object instance, B b) {",
-        "    ((GenericClass<A, B>) instance).register(b);",
-        "  }",
-        "}");
-    assertAbout(javaSource())
-        .that(file)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expected);
-  }
-
-  @Test public void subclassedGenericMembersInjectors() {
-    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A() {}",
-        "}");
-    JavaFileObject a2 = JavaFileObjects.forSourceLines("test.A2",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A2 {",
-        "  @Inject A2() {}",
-        "}");
-    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class Parent<X, Y> {",
-        "  @Inject X x;",
-        "  @Inject Y y;",
-        "  @Inject A2 a2;",
-        "",
-        "  @Inject Parent() {}",
-        "}");
-    JavaFileObject child = JavaFileObjects.forSourceLines("test.Child",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class Child<T> extends Parent<T, A> {",
-        "  @Inject A a;",
-        "  @Inject T t;",
-        "",
-        "  @Inject Child() {}",
-        "}");
-    JavaFileObject expected = JavaFileObjects.forSourceLines(
-        "test.Child_MembersInjector",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        IMPORT_GENERATED_ANNOTATION,
-        "import javax.inject.Provider;",
-        "",
-        GENERATED_ANNOTATION,
-        "public final class Child_MembersInjector<T>",
-        "    implements MembersInjector<Child<T>> {",
-        "  private final Provider<T> tAndXProvider;",
-        "  private final Provider<A> aAndYProvider;",
-        "  private final Provider<A2> a2Provider;",
-        "",
-        "  public Child_MembersInjector(",
-        "      Provider<T> tAndXProvider, Provider<A> aAndYProvider, Provider<A2> a2Provider) {",
-        "    this.tAndXProvider = tAndXProvider;",
-        "    this.aAndYProvider = aAndYProvider;",
-        "    this.a2Provider = a2Provider;",
-        "  }",
-        "",
-        "  public static <T> MembersInjector<Child<T>> create(",
-        "      Provider<T> tAndXProvider, Provider<A> aAndYProvider, Provider<A2> a2Provider) {",
-        "    return new Child_MembersInjector<T>(tAndXProvider, aAndYProvider, a2Provider);",
-        "  }",
-        "",
-        "  @Override",
-        "  public void injectMembers(Child<T> instance) {",
-        "    Parent_MembersInjector.injectX(instance, tAndXProvider.get());",
-        "    Parent_MembersInjector.injectY(instance, aAndYProvider.get());",
-        "    Parent_MembersInjector.injectA2(instance, a2Provider.get());",
-        "    injectA(instance, aAndYProvider.get());",
-        "    injectT(instance, tAndXProvider.get());",
-        "  }",
-        "",
-        "  public static <T> void injectA(Object instance, Object a) {",
-        "    ((Child<T>) instance).a = (A) a;",
-        "  }",
-        "",
-        "  public static <T> void injectT(Object instance, T t) {",
-        "    ((Child<T>) instance).t = t;",
-        "  }",
-        "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(a, a2, parent, child))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expected);
-  }
-
-  @Test public void fieldInjection() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.FieldInjection",
-        "package test;",
-        "",
-        "import dagger.Lazy;",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "class FieldInjection {",
-        "  @Inject String string;",
-        "  @Inject Lazy<String> lazyString;",
-        "  @Inject Provider<String> stringProvider;",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.FieldInjection_MembersInjector",
-            "package test;",
-            "",
-            "import dagger.Lazy;",
-            "import dagger.MembersInjector;",
-            "import dagger.internal.DoubleCheck;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class FieldInjection_MembersInjector",
-            "    implements MembersInjector<FieldInjection> {",
-            "  private final Provider<String> stringProvider;",
-            "",
-            "  public FieldInjection_MembersInjector(Provider<String> stringProvider) {",
-            "    this.stringProvider = stringProvider;",
-            "  }",
-            "",
-            "  public static MembersInjector<FieldInjection> create(",
-            "      Provider<String> stringProvider) {",
-            "    return new FieldInjection_MembersInjector(stringProvider);",
-            "  }",
-            "",
-            "  @Override",
-            "  public void injectMembers(FieldInjection instance) {",
-            "    injectString(instance, stringProvider.get());",
-            "    injectLazyString(instance, DoubleCheck.lazy(stringProvider));",
-            "    injectStringProvider(instance, stringProvider);",
-            "  }",
-            "",
-            "  public static void injectString(Object instance, String string) {",
-            "    ((FieldInjection) instance).string = string;",
-            "  }",
-            "",
-            "  public static void injectLazyString(Object instance, Lazy<String> lazyString) {",
-            "    ((FieldInjection) instance).lazyString = lazyString;",
-            "  }",
-            "",
-            "  public static void injectStringProvider(",
-            "      Object instance, Provider<String> stringProvider) {",
-            "    ((FieldInjection) instance).stringProvider = stringProvider;",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(file)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expected);
-  }
-
-  @Test public void methodInjection() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.MethodInjection",
-        "package test;",
-        "",
-        "import dagger.Lazy;",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "class MethodInjection {",
-        "  @Inject void noArgs() {}",
-        "  @Inject void oneArg(String string) {}",
-        "  @Inject void manyArgs(",
-        "      String string, Lazy<String> lazyString, Provider<String> stringProvider) {}",
-        "}");
-    JavaFileObject expected =
-        JavaFileObjects.forSourceLines(
-            "test.MethodInjection_MembersInjector",
-            "package test;",
-            "",
-            "import dagger.Lazy;",
-            "import dagger.MembersInjector;",
-            "import dagger.internal.DoubleCheck;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class MethodInjection_MembersInjector",
-            "     implements MembersInjector<MethodInjection> {",
-            "",
-            "  private final Provider<String> stringProvider;",
-            "",
-            "  public MethodInjection_MembersInjector(Provider<String> stringProvider) {",
-            "    this.stringProvider = stringProvider;",
-            "  }",
-            "",
-            "  public static MembersInjector<MethodInjection> create(",
-            "      Provider<String> stringProvider) {",
-            "    return new MethodInjection_MembersInjector(stringProvider);",
-            "  }",
-            "",
-            "  @Override",
-            "  public void injectMembers(MethodInjection instance) {",
-            "    injectNoArgs(instance);",
-            "    injectOneArg(instance, stringProvider.get());",
-            "    injectManyArgs(",
-            "        instance,",
-            "        stringProvider.get(),",
-            "        DoubleCheck.lazy(stringProvider),",
-            "        stringProvider);",
-            "  }",
-            "",
-            "  public static void injectNoArgs(Object instance) {",
-            "    ((MethodInjection) instance).noArgs();",
-            "  }",
-            "",
-            "  public static void injectOneArg(Object instance, String string) {",
-            "    ((MethodInjection) instance).oneArg(string);",
-            "  }",
-            "",
-            "  public static void injectManyArgs(",
-            "      Object instance,",
-            "      String string,",
-            "      Lazy<String> lazyString,",
-            "      Provider<String> stringProvider) {",
-            "    ((MethodInjection) instance).manyArgs(string, lazyString, stringProvider);",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(file)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expected);
-  }
-
-  @Test
-  public void mixedMemberInjection() {
-    JavaFileObject file = JavaFileObjects.forSourceLines(
-        "test.MixedMemberInjection",
-        "package test;",
-        "",
-        "import dagger.Lazy;",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "class MixedMemberInjection {",
-        "  @Inject String string;",
-        "  @Inject void setString(String s) {}",
-        "  @Inject Object object;",
-        "  @Inject void setObject(Object o) {}",
-        "}");
-    JavaFileObject expected = JavaFileObjects.forSourceLines(
-        "test.MixedMemberInjection_MembersInjector",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        IMPORT_GENERATED_ANNOTATION,
-        "import javax.inject.Provider;",
-        "",
-        GENERATED_ANNOTATION,
-        "public final class MixedMemberInjection_MembersInjector",
-        "    implements MembersInjector<MixedMemberInjection> {",
-        "",
-        "  private final Provider<String> stringAndSProvider;",
-        "  private final Provider<Object> objectAndOProvider;",
-        "",
-        "  public MixedMemberInjection_MembersInjector(",
-        "      Provider<String> stringAndSProvider,",
-        "      Provider<Object> objectAndOProvider) {",
-        "    this.stringAndSProvider = stringAndSProvider;",
-        "    this.objectAndOProvider = objectAndOProvider;",
-        "  }",
-        "",
-        "  public static MembersInjector<MixedMemberInjection> create(",
-        "      Provider<String> stringAndSProvider,",
-        "      Provider<Object> objectAndOProvider) {",
-        "    return new MixedMemberInjection_MembersInjector(",
-        "        stringAndSProvider, objectAndOProvider);",
-        "  }",
-        "",
-        "  @Override",
-        "  public void injectMembers(MixedMemberInjection instance) {",
-        "    injectString(instance, stringAndSProvider.get());",
-        "    injectObject(instance, objectAndOProvider.get());",
-        "    injectSetString(instance, stringAndSProvider.get());",
-        "    injectSetObject(instance, objectAndOProvider.get());",
-        "  }",
-        "",
-        "  public static void injectString(Object instance, String string) {",
-        "    ((MixedMemberInjection) instance).string = string;",
-        "  }",
-        "",
-        "  public static void injectObject(Object instance, Object object) {",
-        "    ((MixedMemberInjection) instance).object = object;",
-        "  }",
-        "",
-        "  public static void injectSetString(Object instance, String s) {",
-        "    ((MixedMemberInjection) instance).setString(s);",
-        "  }",
-        "",
-        "  public static void injectSetObject(Object instance, Object o) {",
-        "    ((MixedMemberInjection) instance).setObject(o);",
-        "  }",
-        "}");
-    assertAbout(javaSource())
-        .that(file)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expected);
-  }
-
-  @Test public void injectConstructorAndMembersInjection() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.AllInjections",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class AllInjections {",
-        "  @Inject String s;",
-        "  @Inject AllInjections(String s) {}",
-        "  @Inject void s(String s) {}",
-        "}");
-    JavaFileObject expectedMembersInjector = JavaFileObjects.forSourceLines(
-        "test.AllInjections_MembersInjector",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        IMPORT_GENERATED_ANNOTATION,
-        "import javax.inject.Provider;",
-        "",
-        GENERATED_ANNOTATION,
-        "public final class AllInjections_MembersInjector ",
-        "    implements MembersInjector<AllInjections> {",
-        "",
-        "  private final Provider<String> sProvider;",
-        "",
-        "  public AllInjections_MembersInjector(Provider<String> sProvider) {",
-        "    this.sProvider = sProvider;",
-        "  }",
-        "",
-        "  public static MembersInjector<AllInjections> create(Provider<String> sProvider) {",
-        "      return new AllInjections_MembersInjector(sProvider);",
-        "  }",
-        "",
-        "  @Override",
-        "  public void injectMembers(AllInjections instance) {",
-        "    injectS(instance, sProvider.get());",
-        "    injectS2(instance, sProvider.get());",
-        "  }",
-        "",
-        // TODO(b/64477506): now that these all take "object", it would be nice to rename "instance"
-        // to the type name
-        "  public static void injectS(Object instance, String s) {",
-        "    ((AllInjections) instance).s = s;",
-        "  }",
-        "",
-        "  public static void injectS2(Object instance, String s) {",
-        "    ((AllInjections) instance).s(s);",
-        "  }",
-        "",
-        "}");
-    assertAbout(javaSource())
-        .that(file)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expectedMembersInjector);
-  }
-
-  @Test public void supertypeMembersInjection() {
-    JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "class A {}");
-    JavaFileObject bFile = JavaFileObjects.forSourceLines("test.B",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class B extends A {",
-        "  @Inject String s;",
-        "}");
-    JavaFileObject expectedMembersInjector = JavaFileObjects.forSourceLines(
-        "test.AllInjections_MembersInjector",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        IMPORT_GENERATED_ANNOTATION,
-        "import javax.inject.Provider;",
-        "",
-        GENERATED_ANNOTATION,
-        "public final class B_MembersInjector implements MembersInjector<B> {",
-        "  private final Provider<String> sProvider;",
-        "",
-        "  public B_MembersInjector(Provider<String> sProvider) {",
-        "    this.sProvider = sProvider;",
-        "  }",
-        "",
-        "  public static MembersInjector<B> create(Provider<String> sProvider) {",
-        "      return new B_MembersInjector(sProvider);",
-        "  }",
-        "",
-        "  @Override",
-        "  public void injectMembers(B instance) {",
-        "    injectS(instance, sProvider.get());",
-        "  }",
-        "",
-        "  public static void injectS(Object instance, String s) {",
-        "    ((B) instance).s = s;",
-        "  }",
-        "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(aFile, bFile))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expectedMembersInjector);
-  }
-
-  @Test
-  public void simpleComponentWithNesting() {
-    JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines(
-          "test.OuterType",
-          "package test;",
-          "",
-          "import dagger.Component;",
-          "import javax.inject.Inject;",
-          "",
-          "final class OuterType {",
-          "  static class A {",
-          "    @Inject A() {}",
-          "  }",
-          "  static class B {",
-          "    @Inject A a;",
-          "  }",
-          "  @Component interface SimpleComponent {",
-          "    A a();",
-          "    void inject(B b);",
-          "  }",
-          "}");
-    JavaFileObject bMembersInjector = JavaFileObjects.forSourceLines(
-          "test.OuterType_B_MembersInjector",
-          "package test;",
-          "",
-          "import dagger.MembersInjector;",
-          IMPORT_GENERATED_ANNOTATION,
-          "import javax.inject.Provider;",
-          "",
-          GENERATED_ANNOTATION,
-          "public final class OuterType_B_MembersInjector",
-          "    implements MembersInjector<OuterType.B> {",
-          "  private final Provider<OuterType.A> aProvider;",
-          "",
-          "  public OuterType_B_MembersInjector(Provider<OuterType.A> aProvider) {",
-          "    this.aProvider = aProvider;",
-          "  }",
-          "",
-          "  public static MembersInjector<OuterType.B> create(Provider<OuterType.A> aProvider) {",
-          "    return new OuterType_B_MembersInjector(aProvider);",
-          "  }",
-          "",
-          "  @Override",
-          "  public void injectMembers(OuterType.B instance) {",
-          "    injectA(instance, aProvider.get());",
-          "  }",
-          "",
-          "  public static void injectA(Object instance, Object a) {",
-          "    ((OuterType.B) instance).a = (OuterType.A) a;",
-          "  }",
-          "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(nestedTypesFile))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(bMembersInjector);
-  }
-
-  @Test
-  public void componentWithNestingAndGeneratedType() {
-    JavaFileObject nestedTypesFile =
-        JavaFileObjects.forSourceLines(
-            "test.OuterType",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Inject;",
-            "",
-            "final class OuterType {",
-            "  @Inject GeneratedType generated;",
-            "  static class A {",
-            "    @Inject A() {}",
-            "  }",
-            "  static class B {",
-            "    @Inject A a;",
-            "  }",
-            "  @Component interface SimpleComponent {",
-            "    A a();",
-            "    void inject(B b);",
-            "  }",
-            "}");
-    JavaFileObject bMembersInjector =
-        JavaFileObjects.forSourceLines(
-            "test.OuterType_B_MembersInjector",
-            "package test;",
-            "",
-            "import dagger.MembersInjector;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class OuterType_B_MembersInjector",
-            "    implements MembersInjector<OuterType.B> {",
-            "  private final Provider<OuterType.A> aProvider;",
-            "",
-            "  public OuterType_B_MembersInjector(Provider<OuterType.A> aProvider) {",
-            "    this.aProvider = aProvider;",
-            "  }",
-            "",
-            "  public static MembersInjector<OuterType.B> create(",
-            "      Provider<OuterType.A> aProvider) {",
-            "    return new OuterType_B_MembersInjector(aProvider);",
-            "  }",
-            "",
-            "  @Override",
-            "  public void injectMembers(OuterType.B instance) {",
-            "    injectA(instance, aProvider.get());",
-            "  }",
-            "",
-            "  public static void injectA(Object instance, Object a) {",
-            "    ((OuterType.B) instance).a = (OuterType.A) a;",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(nestedTypesFile)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(
-            new ComponentProcessor(),
-            new AbstractProcessor() {
-              private boolean done;
-
-              @Override
-              public Set<String> getSupportedAnnotationTypes() {
-                return ImmutableSet.of("*");
-              }
-
-              @Override
-              public boolean process(
-                  Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-                if (!done) {
-                  done = true;
-                  try (Writer writer =
-                      processingEnv
-                          .getFiler()
-                          .createSourceFile("test.GeneratedType")
-                          .openWriter()) {
-                    writer.write(
-                        Joiner.on('\n')
-                            .join(
-                                "package test;",
-                                "",
-                                "import javax.inject.Inject;",
-                                "",
-                                "class GeneratedType {",
-                                "  @Inject GeneratedType() {}",
-                                "}"));
-                  } catch (IOException e) {
-                    throw new RuntimeException(e);
-                  }
-                }
-                return false;
-              }
-            })
-        .compilesWithoutError()
-        .and()
-        .generatesSources(bMembersInjector);
-  }
-
-  @Test
-  public void lowerCaseNamedMembersInjector_forLowerCaseType() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class foo {",
-            "  @Inject String string;",
-            "}");
-    JavaFileObject fooModule =
-        JavaFileObjects.forSourceLines(
-            "test.fooModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class fooModule {",
-            "  @Provides String string() { return \"foo\"; }",
-            "}");
-    JavaFileObject fooComponent =
-        JavaFileObjects.forSourceLines(
-            "test.fooComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = fooModule.class)",
-            "interface fooComponent {",
-            "  void inject(foo target);",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(foo, fooModule, fooComponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation).generatedFile(CLASS_OUTPUT, "test", "foo_MembersInjector.class");
-  }
-
-  @Test
-  public void fieldInjectionForShadowedMember() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Bar {",
-            "  @Inject Bar() {}",
-            "}");
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Parent { ",
-            "  @Inject Foo object;",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Child extends Parent { ",
-            "  @Inject Bar object;",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface C { ",
-            "  void inject(Child child);",
-            "}");
-
-    JavaFileObject expectedMembersInjector =
-        JavaFileObjects.forSourceLines(
-            "test.Child_MembersInjector",
-            "package test;",
-            "",
-            "import dagger.MembersInjector;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class Child_MembersInjector implements MembersInjector<Child> {",
-            "  private final Provider<Foo> objectProvider;",
-            "  private final Provider<Bar> objectProvider2;",
-            "",
-            "  public Child_MembersInjector(",
-            "        Provider<Foo> objectProvider, Provider<Bar> objectProvider2) {",
-            "    this.objectProvider = objectProvider;",
-            "    this.objectProvider2 = objectProvider2;",
-            "  }",
-            "",
-            "  public static MembersInjector<Child> create(",
-            "      Provider<Foo> objectProvider, Provider<Bar> objectProvider2) {",
-            "    return new Child_MembersInjector(objectProvider, objectProvider2);",
-            "  }",
-            "",
-            "  @Override",
-            "  public void injectMembers(Child instance) {",
-            "    Parent_MembersInjector.injectObject(instance, objectProvider.get());",
-            "    injectObject(instance, objectProvider2.get());",
-            "  }",
-            "",
-            "  public static void injectObject(Object instance, Object object) {",
-            "    ((Child) instance).object = (Bar) object;",
-            "  }",
-            "}");
-
-    assertAbout(javaSources())
-        .that(ImmutableList.of(foo, bar, parent, child, component))
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(expectedMembersInjector);
-  }
-
-  @Test public void privateNestedClassError() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class InnerClass {",
-        "    @Inject int field;",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().withOptions(compilerMode.javacopts()).compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateNestedClassWarning() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static final class InnerClass {",
-        "    @Inject int field;",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                compilerMode.javacopts().append("-Adagger.privateMemberValidation=WARNING"))
-            .compile(file);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining("Dagger does not support injection into private classes")
-        .inFile(file)
-        .onLine(6);
-  }
-
-  @Test public void privateSuperclassIsOkIfNotInjectedInto() {
-    JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class OuterClass {",
-        "  private static class BaseClass {}",
-        "",
-        "  static final class DerivedClass extends BaseClass {",
-        "    @Inject int field;",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().withOptions(compilerMode.javacopts()).compile(file);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void rawFrameworkTypeField() {
-    JavaFileObject file =
-        JavaFileObjects.forSourceLines(
-            "test.RawFrameworkTypes",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "class RawProviderField {",
-            "  @Inject Provider fieldWithRawProvider;",
-            "}",
-            "",
-            "@Component",
-            "interface C {",
-            "  void inject(RawProviderField rawProviderField);",
-            "}");
-
-    Compilation compilation = daggerCompiler().withOptions(compilerMode.javacopts()).compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("javax.inject.Provider cannot be provided")
-        .inFile(file)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void rawFrameworkTypeParameter() {
-    JavaFileObject file =
-        JavaFileObjects.forSourceLines(
-            "test.RawFrameworkTypes",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "class RawProviderParameter {",
-            "  @Inject void methodInjection(Provider rawProviderParameter) {}",
-            "}",
-            "",
-            "@Component",
-            "interface C {",
-            "  void inject(RawProviderParameter rawProviderParameter);",
-            "}");
-
-    Compilation compilation = daggerCompiler().withOptions(compilerMode.javacopts()).compile(file);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("javax.inject.Provider cannot be provided")
-        .inFile(file)
-        .onLineContaining("interface C");
-  }
-
-  @Test
-  public void injectsPrimitive() {
-    JavaFileObject injectedType =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectedType {",
-            "  @Inject InjectedType() {}",
-            "",
-            "  @Inject int primitiveInt;",
-            "  @Inject Integer boxedInt;",
-            "}");
-    JavaFileObject membersInjector =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType_MembersInjector",
-            "package test;",
-            "",
-            "import dagger.MembersInjector;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectedType_MembersInjector ",
-            "    implements MembersInjector<InjectedType> {",
-            "  private final Provider<Integer> boxedIntAndPrimitiveIntProvider;",
-            "",
-            "  public InjectedType_MembersInjector(",
-            "      Provider<Integer> boxedIntAndPrimitiveIntProvider) {",
-            "    this.boxedIntAndPrimitiveIntProvider = boxedIntAndPrimitiveIntProvider;",
-            "  }",
-            "",
-            "  public static MembersInjector<InjectedType> create(",
-            "      Provider<Integer> boxedIntAndPrimitiveIntProvider) {",
-            "    return new InjectedType_MembersInjector(boxedIntAndPrimitiveIntProvider);",
-            "  }",
-            "",
-            "  @Override",
-            "  public void injectMembers(InjectedType instance) {",
-            "    injectPrimitiveInt(instance, boxedIntAndPrimitiveIntProvider.get());",
-            "    injectBoxedInt(instance, boxedIntAndPrimitiveIntProvider.get());",
-            "  }",
-            "",
-            "  public static void injectPrimitiveInt(Object instance, int primitiveInt) {",
-            "    ((InjectedType) instance).primitiveInt = primitiveInt;",
-            "  }",
-            "",
-            "  public static void injectBoxedInt(Object instance, Integer boxedInt) {",
-            "    ((InjectedType) instance).boxedInt = boxedInt;",
-            "  }",
-            "}");
-    JavaFileObject factory =
-        JavaFileObjects.forSourceLines(
-            "test.InjectedType_Factory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class InjectedType_Factory implements Factory<InjectedType> {",
-            "  private final Provider<Integer> boxedIntAndPrimitiveIntProvider;",
-            "",
-            "  public InjectedType_Factory(Provider<Integer> boxedIntAndPrimitiveIntProvider) {",
-            "    this.boxedIntAndPrimitiveIntProvider = boxedIntAndPrimitiveIntProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public InjectedType get() {",
-            "    InjectedType instance = new InjectedType();",
-            "    InjectedType_MembersInjector.injectPrimitiveInt(",
-            "        instance, boxedIntAndPrimitiveIntProvider.get());",
-            "    InjectedType_MembersInjector.injectBoxedInt(",
-            "        instance, boxedIntAndPrimitiveIntProvider.get());",
-            "    return instance;",
-            "  }",
-            "",
-            "  public static InjectedType_Factory create(",
-            "      Provider<Integer> boxedIntAndPrimitiveIntProvider) {",
-            "    return new InjectedType_Factory(boxedIntAndPrimitiveIntProvider);",
-            "  }",
-            "",
-            "  public static InjectedType newInstance() {",
-            "    return new InjectedType();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(injectedType);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.InjectedType_MembersInjector")
-        .hasSourceEquivalentTo(membersInjector);
-    assertThat(compilation)
-        .generatedSourceFile("test.InjectedType_Factory")
-        .hasSourceEquivalentTo(factory);
-  }
-
-  @Test
-  public void accessibility() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "other.Foo",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Inaccessible {",
-            "  @Inject Inaccessible() {}",
-            "  @Inject Foo foo;",
-            "  @Inject void method(Foo foo) {}",
-            "}");
-    JavaFileObject usesInaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessible",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessible {",
-            "  @Inject UsesInaccessible(Inaccessible inaccessible) {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import other.UsesInaccessible;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  UsesInaccessible usesInaccessible();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(foo, inaccessible, usesInaccessible, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("other.Inaccessible_MembersInjector")
-        .hasSourceEquivalentTo(
-            JavaFileObjects.forSourceLines(
-                "other.Inaccessible_MembersInjector",
-                "package other;",
-                "",
-                "import dagger.MembersInjector;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class Inaccessible_MembersInjector",
-                "    implements MembersInjector<Inaccessible> {",
-                "  private final Provider<Foo> fooProvider;",
-                "",
-                "  public Inaccessible_MembersInjector(Provider<Foo> fooProvider) {",
-                "    this.fooProvider = fooProvider;",
-                "  }",
-                "",
-                "  public static MembersInjector<Inaccessible> create(Provider<Foo> fooProvider) {",
-                "    return new Inaccessible_MembersInjector(fooProvider);",
-                "  }",
-                "",
-                "  @Override",
-                "  public void injectMembers(Inaccessible instance) {",
-                "    injectFoo(instance, fooProvider.get());",
-                "    injectMethod(instance, fooProvider.get());",
-                "  }",
-                "",
-                "  public static void injectFoo(Object instance, Object foo) {",
-                "    ((Inaccessible) instance).foo = (Foo) foo;",
-                "  }",
-                "",
-                "  public static void injectMethod(Object instance, Object foo) {",
-                "    ((Inaccessible) instance).method((Foo) foo);",
-                "  }",
-                "}"));
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import other.Foo_Factory;",
-            "import other.Inaccessible_Factory;",
-            "import other.Inaccessible_MembersInjector;",
-            "import other.UsesInaccessible;",
-            "import other.UsesInaccessible_Factory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private Object getInaccessible() {",
-            "    return injectInaccessible(Inaccessible_Factory.newInstance());",
-            "  }",
-            "",
-            "  @Override",
-            "  public UsesInaccessible usesInaccessible() {",
-            "    return UsesInaccessible_Factory.newInstance(",
-            "        getInaccessible());",
-            "  }",
-            "",
-            // TODO(ronshapiro): if possible, it would be great to rename "instance", but we
-            // need to make sure that this doesn't conflict with any framework field in this or
-            // any parent component
-            "  @CanIgnoreReturnValue",
-            "  private Object injectInaccessible(Object instance) {",
-            "    Inaccessible_MembersInjector.injectFoo(instance, Foo_Factory.newInstance());",
-            "    Inaccessible_MembersInjector.injectMethod(instance, Foo_Factory.newInstance());",
-            "    return instance;",
-            "  }",
-            "}");
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void accessibleRawType_ofInaccessibleType() {
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible",
-            "package other;",
-            "",
-            "class Inaccessible {}");
-    JavaFileObject inaccessiblesModule =
-        JavaFileObjects.forSourceLines(
-            "other.InaccessiblesModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.ArrayList;",
-            "import java.util.List;",
-            "import javax.inject.Provider;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "public class InaccessiblesModule {",
-            // force Provider initialization
-            "  @Provides @Singleton static List<Inaccessible> inaccessibles() {",
-            "    return new ArrayList<>();",
-            "  }",
-            "}");
-    JavaFileObject usesInaccessibles =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessibles",
-            "package other;",
-            "",
-            "import java.util.List;",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessibles {",
-            "  @Inject UsesInaccessibles() {}",
-            "  @Inject List<Inaccessible> inaccessibles;",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "import other.UsesInaccessibles;",
-            "",
-            "@Singleton",
-            "@Component(modules = other.InaccessiblesModule.class)",
-            "interface TestComponent {",
-            "  UsesInaccessibles usesInaccessibles();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(inaccessible, inaccessiblesModule, usesInaccessibles, component);
-    assertThat(compilation).succeeded();
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-                "import other.InaccessiblesModule;",
-                "import other.InaccessiblesModule_InaccessiblesFactory;",
-                "import other.UsesInaccessibles;",
-                "import other.UsesInaccessibles_Factory;",
-                "import other.UsesInaccessibles_MembersInjector;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Object listOfInaccessible = new MemoizedSentinel();",
-                "",
-                "  private List getListOfInaccessible() {",
-                "    Object local = listOfInaccessible;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = listOfInaccessible;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = InaccessiblesModule_InaccessiblesFactory.inaccessibles();",
-                "          listOfInaccessible =",
-                "              DoubleCheck.reentrantCheck(listOfInaccessible, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (List) local;",
-                "  }")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  @SuppressWarnings(\"rawtypes\")",
-                "  private Provider inaccessiblesProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.inaccessiblesProvider =",
-                "        DoubleCheck.provider(InaccessiblesModule_InaccessiblesFactory.create());",
-                "  }")
-            .addLines(
-                "",
-                "  @Override",
-                "  public UsesInaccessibles usesInaccessibles() {",
-                "    return injectUsesInaccessibles(",
-                "        UsesInaccessibles_Factory.newInstance());",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private UsesInaccessibles injectUsesInaccessibles(",
-                "        UsesInaccessibles instance) {",
-                "    UsesInaccessibles_MembersInjector.injectInaccessibles(")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "        instance, (List) getListOfInaccessible());")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "        instance, (List) inaccessiblesProvider.get());")
-            .addLines(
-                "    return instance;",
-                "  }",
-                "}")
-            .build();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void publicSupertypeHiddenSubtype() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "other.Foo",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "other.Supertype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "public class Supertype<T> {",
-            "  @Inject T t;",
-            "}");
-    JavaFileObject subtype =
-        JavaFileObjects.forSourceLines(
-            "other.Subtype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Subtype extends Supertype<Foo> {",
-            "  @Inject Subtype() {}",
-            "}");
-    JavaFileObject injectsSubtype =
-        JavaFileObjects.forSourceLines(
-            "other.InjectsSubtype",
-            "package other;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "public class InjectsSubtype {",
-            "  @Inject InjectsSubtype(Subtype s) {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  other.InjectsSubtype injectsSubtype();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(foo, supertype, subtype, injectsSubtype, component);
-    assertThat(compilation).succeeded();
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.errorprone.annotations.CanIgnoreReturnValue;",
-            "import other.Foo_Factory;",
-            "import other.InjectsSubtype;",
-            "import other.InjectsSubtype_Factory;",
-            "import other.Subtype_Factory;",
-            "import other.Supertype;",
-            "import other.Supertype_MembersInjector;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private Object getSubtype() {",
-            "    return injectSubtype(Subtype_Factory.newInstance());",
-            "  }",
-            "",
-            "  @Override",
-            "  public InjectsSubtype injectsSubtype() {",
-            "    return InjectsSubtype_Factory.newInstance(getSubtype());",
-            "  }",
-            "",
-            "  @CanIgnoreReturnValue",
-            "  private Object injectSubtype(Object instance) {",
-            "    Supertype_MembersInjector.injectT(",
-            "        (Supertype) instance, Foo_Factory.newInstance());",
-            "    return instance;",
-            "  }",
-            "}");
-
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MembersInjectionValidationTest.java b/javatests/dagger/internal/codegen/MembersInjectionValidationTest.java
deleted file mode 100644
index 68d5daa..0000000
--- a/javatests/dagger/internal/codegen/MembersInjectionValidationTest.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests that errors are reported for invalid members injection methods and {@link
- * dagger.MembersInjector} dependency requests.
- */
-@RunWith(JUnit4.class)
-public class MembersInjectionValidationTest {
-  @Test
-  public void membersInjectDependsOnUnboundedType() {
-    JavaFileObject injectsUnboundedType =
-        JavaFileObjects.forSourceLines(
-            "test.InjectsUnboundedType",
-            "package test;",
-            "",
-            "import dagger.MembersInjector;",
-            "import java.util.ArrayList;",
-            "import javax.inject.Inject;",
-            "",
-            "class InjectsUnboundedType {",
-            "  @Inject MembersInjector<ArrayList<?>> listInjector;",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(injectsUnboundedType);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Cannot inject members into types with unbounded type arguments: "
-                + "java.util.ArrayList<?>")
-        .inFile(injectsUnboundedType)
-        .onLineContaining("@Inject MembersInjector<ArrayList<?>> listInjector;");
-  }
-
-  @Test
-  public void membersInjectPrimitive() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  void inject(int primitive);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into int")
-        .inFile(component)
-        .onLineContaining("void inject(int primitive);");
-  }
-
-  @Test
-  public void membersInjectArray() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  void inject(Object[] array);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into java.lang.Object[]")
-        .inFile(component)
-        .onLineContaining("void inject(Object[] array);");
-  }
-
-  @Test
-  public void membersInjectorOfArray() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  MembersInjector<Object[]> objectArrayInjector();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into java.lang.Object[]")
-        .inFile(component)
-        .onLineContaining("objectArrayInjector();");
-  }
-
-  @Test
-  public void membersInjectRawType() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Set;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  void inject(Set rawSet);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("Cannot inject members into raw type java.util.Set");
-  }
-
-  @Test
-  public void qualifiedMembersInjector() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "import javax.inject.Named;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  @Named(\"foo\") MembersInjector<Object> objectInjector();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into qualified types")
-        .inFile(component)
-        .onLineContaining("objectInjector();");
-  }
-
-  @Test
-  public void qualifiedMembersInjectionMethod() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "import javax.inject.Named;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  @Named(\"foo\") void injectObject(Object object);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into qualified types")
-        .inFile(component)
-        .onLineContaining("injectObject(Object object);");
-  }
-
-  @Test
-  public void qualifiedMembersInjectionMethodParameter() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "import javax.inject.Named;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  void injectObject(@Named(\"foo\") Object object);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Cannot inject members into qualified types")
-        .inFile(component)
-        .onLineContaining("injectObject(@Named(\"foo\") Object object);");
-  }
-
-  @Test
-  public void staticFieldInjection() {
-    JavaFileObject injected =
-        JavaFileObjects.forSourceLines(
-            "test.Injected",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class Injected {",
-            "  @Inject static Object object;",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  void inject(Injected injected);",
-            "}");
-    Compilation compilation = daggerCompiler().compile(injected, component);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("static fields").inFile(injected).onLine(6);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MethodSignatureFormatterTest.java b/javatests/dagger/internal/codegen/MethodSignatureFormatterTest.java
deleted file mode 100644
index 687c29a..0000000
--- a/javatests/dagger/internal/codegen/MethodSignatureFormatterTest.java
+++ /dev/null
@@ -1,74 +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.truth.Truth.assertThat;
-import static javax.lang.model.util.ElementFilter.methodsIn;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.testing.compile.CompilationRule;
-import dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.InnerClass;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.inject.Singleton;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MethodSignatureFormatterTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-
-  static class OuterClass {
-    @interface Foo {
-       Class<?> bar();
-    }
-
-    static class InnerClass {
-      @Foo(bar = String.class)
-      @Singleton
-      String foo(
-          @SuppressWarnings("unused") int a,
-          @SuppressWarnings("unused") ImmutableList<Boolean> blah) {
-        return "foo";
-      }
-    }
-  }
-
-  @Test public void methodSignatureTest() {
-    DaggerElements elements =
-        new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
-    DaggerTypes types = new DaggerTypes(compilationRule.getTypes(), elements);
-    TypeElement inner = elements.getTypeElement(InnerClass.class);
-    ExecutableElement method = Iterables.getOnlyElement(methodsIn(inner.getEnclosedElements()));
-    String formatted = new MethodSignatureFormatter(types).format(method);
-    // This is gross, but it turns out that annotation order is not guaranteed when getting
-    // all the AnnotationMirrors from an Element, so I have to test this chopped-up to make it
-    // less brittle.
-    assertThat(formatted).contains("@Singleton");
-    assertThat(formatted).doesNotContain("@javax.inject.Singleton"); // maybe more importantly
-    assertThat(formatted)
-        .contains("@dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.Foo"
-            + "(bar=String.class)");
-    assertThat(formatted).contains(" String "); // return type compressed
-    assertThat(formatted).contains("int, ImmutableList<Boolean>)"); // parameters compressed.
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MissingAndroidProcessorTest.java b/javatests/dagger/internal/codegen/MissingAndroidProcessorTest.java
deleted file mode 100644
index 0f91e0e..0000000
--- a/javatests/dagger/internal/codegen/MissingAndroidProcessorTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MissingAndroidProcessorTest {
-  @Test
-  public void missingProcessor() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.android.ContributesAndroidInjector;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @ContributesAndroidInjector",
-            "  Object o();",
-            "}");
-    JavaFileObject contributesAndroidInjectorStub =
-        JavaFileObjects.forSourceLines(
-            "dagger.android.ContributesAndroidInjector",
-            "package dagger.android;",
-            "",
-            "public @interface ContributesAndroidInjector {}");
-    Compilation compilation = daggerCompiler().compile(module, contributesAndroidInjectorStub);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("dagger.android.processor.AndroidProcessor")
-        .inFile(module)
-        .onLine(9);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java b/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java
deleted file mode 100644
index e2f9634..0000000
--- a/javatests/dagger/internal/codegen/MissingBindingSuggestionsTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MissingBindingSuggestionsTest {
-  private static JavaFileObject injectable(String className, String constructorParams) {
-    return JavaFileObjects.forSourceLines("test." + className,
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class " + className +" {",
-        "  @Inject " + className + "(" + constructorParams + ") {}",
-        "}");
-  }
-
-  private static JavaFileObject emptyInterface(String interfaceName) {
-    return JavaFileObjects.forSourceLines("test." + interfaceName,
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "interface " + interfaceName +" {}");
-  }
-
-  @Test public void suggestsBindingInSeparateComponent() {
-    JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface FooComponent {",
-        "  Foo getFoo();",
-        "}");
-    JavaFileObject barModule = JavaFileObjects.forSourceLines("test.BarModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class BarModule {",
-        "  @Provides Bar provideBar() {return null;}",
-        "}");
-    JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = {BarModule.class})",
-        "interface BarComponent {",
-        "  Bar getBar();",
-        "}");
-    JavaFileObject foo = injectable("Foo", "Bar bar");
-    JavaFileObject bar = emptyInterface("Bar");
-
-    JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TopComponent {",
-        "  FooComponent getFoo();",
-        "  BarComponent getBar(BarModule barModule);",
-        "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(fooComponent, barComponent, topComponent, foo, bar, barModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("A binding with matching key exists in component: test.BarComponent");
-  }
-
-  @Test public void suggestsBindingInNestedSubcomponent() {
-    JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface FooComponent {",
-        "  Foo getFoo();",
-        "}");
-    JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent()",
-        "interface BarComponent {",
-        "  BazComponent getBaz();",
-        "}");
-    JavaFileObject bazModule = JavaFileObjects.forSourceLines("test.BazModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class BazModule {",
-        "  @Provides Baz provideBaz() {return null;}",
-        "}");
-    JavaFileObject bazComponent = JavaFileObjects.forSourceLines("test.BazComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = {BazModule.class})",
-        "interface BazComponent {",
-        "  Baz getBaz();",
-        "}");
-    JavaFileObject foo = injectable("Foo", "Baz baz");
-    JavaFileObject baz = emptyInterface("Baz");
-
-    JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TopComponent {",
-        "  FooComponent getFoo();",
-        "  BarComponent getBar();",
-        "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .compile(fooComponent, barComponent, bazComponent, topComponent, foo, baz, bazModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("A binding with matching key exists in component: test.BazComponent");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java
deleted file mode 100644
index 8eaa8d5..0000000
--- a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MissingBindingValidationTest {
-  @Test
-  public void dependOnInterface() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.MyComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface MyComponent {",
-        "  Foo getFoo();",
-        "}");
-    JavaFileObject injectable = JavaFileObjects.forSourceLines("test.Foo",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class Foo {",
-        "  @Inject Foo(Bar bar) {}",
-        "}");
-    JavaFileObject nonInjectable = JavaFileObjects.forSourceLines("test.Bar",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "interface Bar {}");
-    Compilation compilation = daggerCompiler().compile(component, injectable, nonInjectable);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.Bar cannot be provided without an @Provides-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface MyComponent");
-  }
-
-  @Test
-  public void entryPointDependsOnInterface() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "",
-            "  @Component()",
-            "  interface AComponent {",
-            "    A getA();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "[Dagger/MissingBinding] test.TestClass.A cannot be provided "
-                + "without an @Provides-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test
-  public void entryPointDependsOnQualifiedInterface() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Qualifier;",
-            "",
-            "final class TestClass {",
-            "  @Qualifier @interface Q {}",
-            "  interface A {}",
-            "",
-            "  @Component()",
-            "  interface AComponent {",
-            "    @Q A qualifiedA();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "[Dagger/MissingBinding] @test.TestClass.Q test.TestClass.A cannot be provided "
-                + "without an @Provides-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test public void constructorInjectionWithoutAnnotation() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "final class TestClass {",
-        "  static class A {",
-        "    A() {}",
-        "  }",
-        "",
-        "  @Component()",
-        "  interface AComponent {",
-        "    A getA();",
-        "  }",
-        "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestClass.A cannot be provided without an @Inject constructor or an "
-                + "@Provides-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test public void membersInjectWithoutProvision() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "final class TestClass {",
-        "  static class A {",
-        "    @Inject A() {}",
-        "  }",
-        "",
-        "  static class B {",
-        "    @Inject A a;",
-        "  }",
-        "",
-        "  @Component()",
-        "  interface AComponent {",
-        "    B getB();",
-        "  }",
-        "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestClass.B cannot be provided without an @Inject constructor or an "
-                + "@Provides-annotated method. This type supports members injection but cannot be "
-                + "implicitly provided.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test
-  public void missingBindingWithSameKeyAsMembersInjectionMethod() {
-    JavaFileObject self =
-        JavaFileObjects.forSourceLines(
-            "test.Self",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "class Self {",
-            "  @Inject Provider<Self> selfProvider;",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.SelfComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface SelfComponent {",
-            "  void inject(Self target);",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(self, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.Self cannot be provided without an @Inject constructor")
-        .inFile(component)
-        .onLineContaining("interface SelfComponent");
-  }
-
-  @Test
-  public void genericInjectClassWithWildcardDependencies() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  Foo<? extends Number> foo();",
-            "}");
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class Foo<T> {",
-            "  @Inject Foo(T t) {}",
-            "}");
-    Compilation compilation = daggerCompiler().compile(component, foo);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Foo<? extends java.lang.Number> cannot be provided "
-                + "without an @Provides-annotated method");
-  }
-
-  @Test public void longChainOfDependencies() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Lazy;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Named;",
-            "import javax.inject.Provider;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "",
-            "  static class B {",
-            "    @Inject B(A a) {}",
-            "  }",
-            "",
-            "  static class C {",
-            "    @Inject B b;",
-            "    @Inject C(X x) {}",
-            "  }",
-            "",
-            "  interface D { }",
-            "",
-            "  static class DImpl implements D {",
-            "    @Inject DImpl(C c, B b) {}",
-            "  }",
-            "",
-            "  static class X {",
-            "    @Inject X() {}",
-            "  }",
-            "",
-            "  @Module",
-            "  static class DModule {",
-            "    @Provides @Named(\"slim shady\") D d(X x1, DImpl impl, X x2) { return impl; }",
-            "  }",
-            "",
-            "  @Component(modules = { DModule.class })",
-            "  interface AComponent {",
-            "    @Named(\"slim shady\") D getFoo();",
-            "    C injectC(C c);",
-            "    Provider<C> cProvider();",
-            "    Lazy<C> lazyC();",
-            "    Provider<Lazy<C>> lazyCProvider();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.TestClass.A cannot be provided without an @Provides-annotated method.",
-                "    test.TestClass.A is injected at",
-                "        test.TestClass.B(a)",
-                "    test.TestClass.B is injected at",
-                "        test.TestClass.C.b",
-                "    test.TestClass.C is injected at",
-                "        test.TestClass.AComponent.injectC(test.TestClass.C)",
-                "The following other entry points also depend on it:",
-                "    test.TestClass.AComponent.getFoo()",
-                "    test.TestClass.AComponent.cProvider()",
-                "    test.TestClass.AComponent.lazyC()",
-                "    test.TestClass.AComponent.lazyCProvider()"))
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test
-  public void bindsMethodAppearsInTrace() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "TestComponent",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  TestInterface testInterface();",
-            "}");
-    JavaFileObject interfaceFile =
-        JavaFileObjects.forSourceLines("TestInterface", "interface TestInterface {}");
-    JavaFileObject implementationFile =
-        JavaFileObjects.forSourceLines(
-            "TestImplementation",
-            "import javax.inject.Inject;",
-            "",
-            "final class TestImplementation implements TestInterface {",
-            "  @Inject TestImplementation(String missingBinding) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "TestModule",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Binds abstract TestInterface bindTestInterface(TestImplementation implementation);",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(component, module, interfaceFile, implementationFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.String cannot be provided without an @Inject constructor or an "
-                    + "@Provides-annotated method.",
-                "    java.lang.String is injected at",
-                "        TestImplementation(missingBinding)",
-                "    TestImplementation is injected at",
-                "        TestModule.bindTestInterface(implementation)",
-                "    TestInterface is provided at",
-                "        TestComponent.testInterface()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test public void resolvedParametersInDependencyTrace() {
-    JavaFileObject generic = JavaFileObjects.forSourceLines("test.Generic",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "final class Generic<T> {",
-        "  @Inject Generic(T t) {}",
-        "}");
-    JavaFileObject testClass = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import java.util.List;",
-        "",
-        "final class TestClass {",
-        "  @Inject TestClass(List list) {}",
-        "}");
-    JavaFileObject usesTest = JavaFileObjects.forSourceLines("test.UsesTest",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class UsesTest {",
-        "  @Inject UsesTest(Generic<TestClass> genericTestClass) {}",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  UsesTest usesTest();",
-        "}");
-
-    Compilation compilation = daggerCompiler().compile(generic, testClass, usesTest, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.List cannot be provided without an @Provides-annotated method.",
-                "    java.util.List is injected at",
-                "        test.TestClass(list)",
-                "    test.TestClass is injected at",
-                "        test.Generic(t)",
-                "    test.Generic<test.TestClass> is injected at",
-                "        test.UsesTest(genericTestClass)",
-                "    test.UsesTest is provided at",
-                "        test.TestComponent.usesTest()"));
-  }
-
-  @Test public void resolvedVariablesInDependencyTrace() {
-    JavaFileObject generic = JavaFileObjects.forSourceLines("test.Generic",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import javax.inject.Provider;",
-        "",
-        "final class Generic<T> {",
-        "  @Inject T t;",
-        "  @Inject Generic() {}",
-        "}");
-    JavaFileObject testClass = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "import java.util.List;",
-        "",
-        "final class TestClass {",
-        "  @Inject TestClass(List list) {}",
-        "}");
-    JavaFileObject usesTest = JavaFileObjects.forSourceLines("test.UsesTest",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class UsesTest {",
-        "  @Inject UsesTest(Generic<TestClass> genericTestClass) {}",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  UsesTest usesTest();",
-        "}");
-
-    Compilation compilation = daggerCompiler().compile(generic, testClass, usesTest, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.util.List cannot be provided without an @Provides-annotated method.",
-                "    java.util.List is injected at",
-                "        test.TestClass(list)",
-                "    test.TestClass is injected at",
-                "        test.Generic.t",
-                "    test.Generic<test.TestClass> is injected at",
-                "        test.UsesTest(genericTestClass)",
-                "    test.UsesTest is provided at",
-                "        test.TestComponent.usesTest()"));
-  }
-
-  @Test
-  public void bindingUsedOnlyInSubcomponentDependsOnBindingOnlyInSubcomponent() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "Parent",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "ParentModule",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides static Object needsString(String string) {",
-            "    return \"needs string: \" + string;",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "Child",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  String string();",
-            "  Object needsString();",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "ChildModule",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ChildModule {",
-            "  @Provides static String string() {",
-            "    return \"child string\";",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, parentModule, child, childModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContainingMatch(
-            "(?s)\\Qjava.lang.String cannot be provided\\E.*\\QChild.needsString()\\E")
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-
-  @Test
-  public void multibindingContributionBetweenAncestorComponentAndEntrypointComponent() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "Parent",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "Child",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  Grandchild grandchild();",
-            "}");
-    JavaFileObject grandchild =
-        JavaFileObjects.forSourceLines(
-            "Grandchild",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Grandchild {",
-            "  Object object();",
-            "}");
-
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "ParentModule",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides static Object dependsOnSet(Set<String> strings) {",
-            "    return \"needs strings: \" + strings;",
-            "  }",
-            "",
-            "  @Provides @IntoSet static String contributesToSet() {",
-            "    return \"parent string\";",
-            "  }",
-            "",
-            "  @Provides int missingDependency(double dub) {",
-            "    return 4;",
-            "  }",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "ChildModule",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "",
-            "@Module",
-            "class ChildModule {",
-            "  @Provides @IntoSet static String contributesToSet(int i) {",
-            "    return \"\" + i;",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().compile(parent, parentModule, child, childModule, grandchild);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContainingMatch(
-            "(?s)\\Qjava.lang.Double cannot be provided\\E.*"
-                + "\\QGrandchild.object() [Parent → Child → Grandchild]\\E$")
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-
-  @Test
-  public void manyDependencies() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Object object();",
-            "  String string();",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Binds abstract Object object(NotBound notBound);",
-            "",
-            "  @Provides static String string(NotBound notBound, Object object) {",
-            "    return notBound.toString();",
-            "  }",
-            "}");
-    JavaFileObject notBound =
-        JavaFileObjects.forSourceLines(
-            "test.NotBound", //
-            "package test;",
-            "",
-            "interface NotBound {}");
-    Compilation compilation = daggerCompiler().compile(component, module, notBound);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "[Dagger/MissingBinding] "
-                    + "test.NotBound cannot be provided without an @Provides-annotated method.",
-                "    test.NotBound is injected at",
-                "        test.TestModule.object(notBound)",
-                "    java.lang.Object is provided at",
-                "        test.TestComponent.object()",
-                "It is also requested at:",
-                "    test.TestModule.string(notBound, …)",
-                "The following other entry points also depend on it:",
-                "    test.TestComponent.string()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-    assertThat(compilation).hadErrorCount(1);
-  }
-
-  @Test
-  public void tooManyRequests() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class Foo {",
-            "  @Inject Foo(",
-            "      String one,",
-            "      String two,",
-            "      String three,",
-            "      String four,",
-            "      String five,",
-            "      String six,",
-            "      String seven,",
-            "      String eight,",
-            "      String nine,",
-            "      String ten,",
-            "      String eleven,",
-            "      String twelve,",
-            "      String thirteen) {",
-            "  }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  String string();",
-            "  Foo foo();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(foo, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "[Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject "
-                    + "constructor or an @Provides-annotated method.",
-                "    java.lang.String is provided at",
-                "        test.TestComponent.string()",
-                "It is also requested at:",
-                "    test.Foo(one, …)",
-                "    test.Foo(…, two, …)",
-                "    test.Foo(…, three, …)",
-                "    test.Foo(…, four, …)",
-                "    test.Foo(…, five, …)",
-                "    test.Foo(…, six, …)",
-                "    test.Foo(…, seven, …)",
-                "    test.Foo(…, eight, …)",
-                "    test.Foo(…, nine, …)",
-                "    test.Foo(…, ten, …)",
-                "    and 3 others"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void tooManyEntryPoints() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  String string1();",
-            "  String string2();",
-            "  String string3();",
-            "  String string4();",
-            "  String string5();",
-            "  String string6();",
-            "  String string7();",
-            "  String string8();",
-            "  String string9();",
-            "  String string10();",
-            "  String string11();",
-            "  String string12();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "[Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject "
-                    + "constructor or an @Provides-annotated method.",
-                "    java.lang.String is provided at",
-                "        test.TestComponent.string1()",
-                "The following other entry points also depend on it:",
-                "    test.TestComponent.string2()",
-                "    test.TestComponent.string3()",
-                "    test.TestComponent.string4()",
-                "    test.TestComponent.string5()",
-                "    test.TestComponent.string6()",
-                "    test.TestComponent.string7()",
-                "    test.TestComponent.string8()",
-                "    test.TestComponent.string9()",
-                "    test.TestComponent.string10()",
-                "    test.TestComponent.string11()",
-                "    and 1 other"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ModelTest.java b/javatests/dagger/internal/codegen/ModelTest.java
deleted file mode 100644
index ee4cf47..0000000
--- a/javatests/dagger/internal/codegen/ModelTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-import static dagger.model.testing.BindingGraphSubject.assertThat;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.model.BindingGraph;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class ModelTest {
-
-  @Test
-  public void cycleTest() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class A {",
-            "  @Inject A(B b) {}",
-            "}");
-    JavaFileObject b =
-        JavaFileObjects.forSourceLines(
-            "test.B",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class B {",
-            "  @Inject B(Provider<A> a) {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-
-    BindingGraphCapturer capturer = new BindingGraphCapturer();
-    Compilation compilation =
-        javac().withProcessors(ComponentProcessor.forTesting(capturer)).compile(a, b, component);
-    assertThat(compilation).succeeded();
-    BindingGraph bindingGraph = capturer.bindingGraphs().get("test.TestComponent");
-    assertThat(bindingGraph).bindingWithKey("test.A").dependsOnBindingWithKey("test.B");
-    assertThat(bindingGraph).bindingWithKey("test.B").dependsOnBindingWithKey("test.A");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java b/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java
deleted file mode 100644
index 50c41ed..0000000
--- a/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java
+++ /dev/null
@@ -1,1552 +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.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
-import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.NPE_FROM_PROVIDES_METHOD;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ModuleFactoryGeneratorTest {
-
-  private static final JavaFileObject NULLABLE =
-      JavaFileObjects.forSourceLines(
-          "test.Nullable", "package test;", "public @interface Nullable {}");
-
-  // TODO(gak): add tests for invalid combinations of scope and qualifier annotations like we have
-  // for @Inject
-
-  @Test public void providesMethodNotInModule() {
-    assertThatMethodInUnannotatedClass("@Provides String provideString() { return null; }")
-        .hasError("@Provides methods can only be present within a @Module or @ProducerModule");
-  }
-
-  @Test public void providesMethodAbstract() {
-    assertThatModuleMethod("@Provides abstract String abstractMethod();")
-        .hasError("@Provides methods cannot be abstract");
-  }
-
-  @Test public void providesMethodPrivate() {
-    assertThatModuleMethod("@Provides private String privateMethod() { return null; }")
-        .hasError("@Provides methods cannot be private");
-  }
-
-  @Test public void providesMethodReturnVoid() {
-    assertThatModuleMethod("@Provides void voidMethod() {}")
-        .hasError("@Provides methods must return a value (not void)");
-  }
-
-  @Test
-  public void providesMethodReturnsProvider() {
-    assertThatModuleMethod("@Provides Provider<String> provideProvider() {}")
-        .hasError("@Provides methods must not return framework types");
-  }
-
-  @Test
-  public void providesMethodReturnsLazy() {
-    assertThatModuleMethod("@Provides Lazy<String> provideLazy() {}")
-        .hasError("@Provides methods must not return framework types");
-  }
-
-  @Test
-  public void providesMethodReturnsMembersInjector() {
-    assertThatModuleMethod("@Provides MembersInjector<String> provideMembersInjector() {}")
-        .hasError("@Provides methods must not return framework types");
-  }
-
-  @Test
-  public void providesMethodReturnsProducer() {
-    assertThatModuleMethod("@Provides Producer<String> provideProducer() {}")
-        .hasError("@Provides methods must not return framework types");
-  }
-
-  @Test
-  public void providesMethodReturnsProduced() {
-    assertThatModuleMethod("@Provides Produced<String> provideProduced() {}")
-        .hasError("@Provides methods must not return framework types");
-  }
-
-  @Test public void providesMethodWithTypeParameter() {
-    assertThatModuleMethod("@Provides <T> String typeParameter() { return null; }")
-        .hasError("@Provides methods may not have type parameters");
-  }
-
-  @Test public void providesMethodSetValuesWildcard() {
-    assertThatModuleMethod("@Provides @ElementsIntoSet Set<?> provideWildcard() { return null; }")
-        .hasError(
-            "@Provides methods must return a primitive, an array, a type variable, "
-                + "or a declared type");
-  }
-
-  @Test public void providesMethodSetValuesRawSet() {
-    assertThatModuleMethod("@Provides @ElementsIntoSet Set provideSomething() { return null; }")
-        .hasError("@Provides methods annotated with @ElementsIntoSet cannot return a raw Set");
-  }
-
-  @Test public void providesMethodSetValuesNotASet() {
-    assertThatModuleMethod(
-            "@Provides @ElementsIntoSet List<String> provideStrings() { return null; }")
-        .hasError("@Provides methods annotated with @ElementsIntoSet must return a Set");
-  }
-
-  @Test public void modulesWithTypeParamsMustBeAbstract() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "final class TestModule<A> {}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Modules with type parameters must be abstract")
-        .inFile(moduleFile)
-        .onLine(6);
-  }
-
-  @Test public void provideOverriddenByNoProvide() {
-    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "class Parent {",
-        "  @Provides String foo() { return null; }",
-        "}");
-    assertThatModuleMethod("String foo() { return null; }")
-        .withDeclaration("@Module class %s extends Parent { %s }")
-        .withAdditionalSources(parent)
-        .hasError(
-            "Binding methods may not be overridden in modules. Overrides: "
-                + "@Provides String test.Parent.foo()");
-  }
-
-  @Test public void provideOverriddenByProvide() {
-    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "class Parent {",
-        "  @Provides String foo() { return null; }",
-        "}");
-    assertThatModuleMethod("@Provides String foo() { return null; }")
-        .withDeclaration("@Module class %s extends Parent { %s }")
-        .withAdditionalSources(parent)
-        .hasError(
-            "Binding methods may not override another method. Overrides: "
-                + "@Provides String test.Parent.foo()");
-  }
-
-  @Test public void providesOverridesNonProvides() {
-    JavaFileObject parent = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "class Parent {",
-        "  String foo() { return null; }",
-        "}");
-    assertThatModuleMethod("@Provides String foo() { return null; }")
-        .withDeclaration("@Module class %s extends Parent { %s }")
-        .withAdditionalSources(parent)
-        .hasError(
-            "Binding methods may not override another method. Overrides: "
-                + "String test.Parent.foo()");
-  }
-
-  @Test public void validatesIncludedModules() {
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.Parent",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = Void.class)",
-        "class TestModule {}");
-
-    Compilation compilation = daggerCompiler().compile(module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.lang.Void is listed as a module, but is not annotated with @Module");
-  }
-
-  @Test public void singleProvidesMethodNoArgs() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String provideString() {",
-        "    return \"\";",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideStringFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideStringFactory implements Factory<String> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideStringFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override public String get() {",
-            "    return provideString(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideStringFactory create(TestModule module) {",
-            "    return new TestModule_ProvideStringFactory(module);",
-            "  }",
-            "",
-            "  public static String provideString(TestModule instance) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideString(), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void singleProvidesMethodNoArgs_disableNullable() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String provideString() {",
-        "    return \"\";",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideStringFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideStringFactory implements Factory<String> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideStringFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override public String get() {",
-            "    return provideString(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideStringFactory create(TestModule module) {",
-            "    return new TestModule_ProvideStringFactory(module);",
-            "  }",
-            "",
-            "  public static String provideString(TestModule instance) {",
-            "    return instance.provideString();",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(moduleFile)
-        .withCompilerOptions("-Adagger.nullableValidation=WARNING")
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void nullableProvides() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides @Nullable String provideString() { return null; }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideStringFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideStringFactory implements Factory<String> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideStringFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override",
-            "  @Nullable",
-            "  public String get() {",
-            "    return provideString(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideStringFactory create(TestModule module) {",
-            "    return new TestModule_ProvideStringFactory(module);",
-            "  }",
-            "",
-            "  @Nullable",
-            "  public static String provideString(TestModule instance) {",
-            "    return instance.provideString();",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(ImmutableList.of(moduleFile, NULLABLE))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void multipleProvidesMethods() {
-    JavaFileObject classXFile = JavaFileObjects.forSourceLines("test.X",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "class X {",
-        "  @Inject public String s;",
-        "}");
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.MembersInjector;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import java.util.Arrays;",
-        "import java.util.List;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides List<Object> provideObjects(",
-        "      @QualifierA Object a, @QualifierB Object b, MembersInjector<X> xInjector) {",
-        "    return Arrays.asList(a, b);",
-        "  }",
-        "",
-        "  @Provides @QualifierA Object provideAObject() {",
-        "    return new Object();",
-        "  }",
-        "",
-        "  @Provides @QualifierB Object provideBObject() {",
-        "    return new Object();",
-        "  }",
-        "}");
-    JavaFileObject listFactoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideObjectsFactory",
-            "package test;",
-            "",
-            "import dagger.MembersInjector;",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            "import java.util.List;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideObjectsFactory",
-            "    implements Factory<List<Object>> {",
-            "  private final TestModule module;",
-            "  private final Provider<Object> aProvider;",
-            "  private final Provider<Object> bProvider;",
-            "  private final Provider<MembersInjector<X>> xInjectorProvider;",
-            "",
-            "  public TestModule_ProvideObjectsFactory(",
-            "      TestModule module,",
-            "      Provider<Object> aProvider,",
-            "      Provider<Object> bProvider,",
-            "      Provider<MembersInjector<X>> xInjectorProvider) {",
-            "    this.module = module;",
-            "    this.aProvider = aProvider;",
-            "    this.bProvider = bProvider;",
-            "    this.xInjectorProvider = xInjectorProvider;",
-            "  }",
-            "",
-            "  @Override public List<Object> get() {",
-            "    return provideObjects(",
-            "        module, aProvider.get(), bProvider.get(), xInjectorProvider.get());",
-            "  }",
-            "",
-            "  public static TestModule_ProvideObjectsFactory create(",
-            "      TestModule module,",
-            "      Provider<Object> aProvider,",
-            "      Provider<Object> bProvider,",
-            "      Provider<MembersInjector<X>> xInjectorProvider) {",
-            "    return new TestModule_ProvideObjectsFactory(",
-            "        module, aProvider, bProvider, xInjectorProvider);",
-            "  }",
-            "",
-            "  public static List<Object> provideObjects(",
-            "      TestModule instance, Object a, Object b, MembersInjector<X> xInjector) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideObjects(a, b, xInjector), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    assertAbout(javaSources()).that(
-            ImmutableList.of(classXFile, moduleFile, QUALIFIER_A, QUALIFIER_B))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(listFactoryFile);
-  }
-
-  @Test public void providesSetElement() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import java.util.logging.Logger;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoSet;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides @IntoSet String provideString() {",
-        "    return \"\";",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideStringFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideStringFactory implements Factory<String> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideStringFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override public String get() {",
-            "    return provideString(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideStringFactory create(TestModule module) {",
-            "    return new TestModule_ProvideStringFactory(module);",
-            "  }",
-            "",
-            "  public static String provideString(TestModule instance) {",
-            "    return Preconditions.checkNotNull(instance.provideString(), "
-                + NPE_FROM_PROVIDES_METHOD
-                + ");",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void providesSetElementWildcard() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import java.util.logging.Logger;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoSet;",
-        "import java.util.ArrayList;",
-        "import java.util.List;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides @IntoSet List<List<?>> provideWildcardList() {",
-        "    return new ArrayList<>();",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideWildcardListFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            "import java.util.List;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideWildcardListFactory implements "
-                + "Factory<List<List<?>>> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideWildcardListFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override public List<List<?>> get() {",
-            "    return provideWildcardList(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideWildcardListFactory create(TestModule module) {",
-            "    return new TestModule_ProvideWildcardListFactory(module);",
-            "  }",
-            "",
-            "  public static List<List<?>> provideWildcardList(TestModule instance) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideWildcardList(), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void providesSetValues() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.ElementsIntoSet;",
-        "import java.util.Set;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides @ElementsIntoSet Set<String> provideStrings() {",
-        "    return null;",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProvideStringsFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProvideStringsFactory implements Factory<Set<String>> {",
-            "  private final TestModule module;",
-            "",
-            "  public TestModule_ProvideStringsFactory(TestModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override public Set<String> get() {",
-            "    return provideStrings(module);",
-            "  }",
-            "",
-            "  public static TestModule_ProvideStringsFactory create(TestModule module) {",
-            "    return new TestModule_ProvideStringsFactory(module);",
-            "  }",
-            "",
-            "  public static Set<String> provideStrings(TestModule instance) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideStrings(), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    assertAbout(javaSource()).that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and().generatesSources(factoryFile);
-  }
-
-  @Test public void multipleProvidesMethodsWithSameName() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides Object provide(int i) {",
-        "    return i;",
-        "  }",
-        "",
-        "  @Provides String provide() {",
-        "    return \"\";",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Cannot have more than one binding method with the same name in a single module")
-        .inFile(moduleFile)
-        .onLine(8);
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Cannot have more than one binding method with the same name in a single module")
-        .inFile(moduleFile)
-        .onLine(12);
-  }
-
-  @Test
-  public void providesMethodThrowsChecked() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides int i() throws Exception {",
-            "    return 0;",
-            "  }",
-            "",
-            "  @Provides String s() throws Throwable {",
-            "    return \"\";",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Provides methods may only throw unchecked exceptions")
-        .inFile(moduleFile)
-        .onLine(8);
-    assertThat(compilation)
-        .hadErrorContaining("@Provides methods may only throw unchecked exceptions")
-        .inFile(moduleFile)
-        .onLine(12);
-  }
-
-  @Test
-  public void providedTypes() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import java.io.Closeable;",
-        "import java.util.Set;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String string() {",
-        "    return null;",
-        "  }",
-        "",
-        "  @Provides Set<String> strings() {",
-        "    return null;",
-        "  }",
-        "",
-        "  @Provides Set<? extends Closeable> closeables() {",
-        "    return null;",
-        "  }",
-        "",
-        "  @Provides String[] stringArray() {",
-        "    return null;",
-        "  }",
-        "",
-        "  @Provides int integer() {",
-        "    return 0;",
-        "  }",
-        "",
-        "  @Provides int[] integers() {",
-        "    return null;",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void privateModule() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "final class Enclosing {",
-        "  @Module private static final class PrivateModule {",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Modules cannot be private")
-        .inFile(moduleFile)
-        .onLine(6);
-  }
-
-  @Test
-  public void enclosedInPrivateModule() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "final class Enclosing {",
-        "  private static final class PrivateEnclosing {",
-        "    @Module static final class TestModule {",
-        "    }",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Modules cannot be enclosed in private types")
-        .inFile(moduleFile)
-        .onLine(7);
-  }
-
-  @Test
-  public void publicModuleNonPublicIncludes() {
-    JavaFileObject publicModuleFile = JavaFileObjects.forSourceLines("test.PublicModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module(includes = {",
-        "    BadNonPublicModule.class, OtherPublicModule.class, OkNonPublicModule.class",
-        "})",
-        "public final class PublicModule {",
-        "}");
-    JavaFileObject badNonPublicModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.BadNonPublicModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class BadNonPublicModule {",
-            "  @Provides",
-            "  int provideInt() {",
-            "    return 42;",
-            "  }",
-            "}");
-    JavaFileObject okNonPublicModuleFile = JavaFileObjects.forSourceLines("test.OkNonPublicModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class OkNonPublicModule {",
-        "  @Provides",
-        "  static String provideString() {",
-        "    return \"foo\";",
-        "  }",
-        "}");
-    JavaFileObject otherPublicModuleFile = JavaFileObjects.forSourceLines("test.OtherPublicModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "public final class OtherPublicModule {",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                publicModuleFile,
-                badNonPublicModuleFile,
-                okNonPublicModuleFile,
-                otherPublicModuleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "This module is public, but it includes non-public (or effectively non-public) modules "
-                + "(test.BadNonPublicModule) that have non-static, non-abstract binding methods. "
-                + "Either reduce the visibility of this module, make the included modules public, "
-                + "or make all of the binding methods on the included modules abstract or static.")
-        .inFile(publicModuleFile)
-        .onLine(8);
-  }
-
-  @Test
-  public void genericSubclassedModule() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.List;",
-            "import java.util.ArrayList;",
-            "",
-            "@Module",
-            "abstract class ParentModule<A extends CharSequence,",
-            "                            B,",
-            "                            C extends Number & Comparable<C>> {",
-            "  @Provides List<B> provideListB(B b) {",
-            "    List<B> list = new ArrayList<B>();",
-            "    list.add(b);",
-            "    return list;",
-            "  }",
-            "",
-            "  @Provides @IntoSet B provideBElement(B b) {",
-            "    return b;",
-            "  }",
-            "",
-            "  @Provides @IntoMap @StringKey(\"b\") B provideBEntry(B b) {",
-            "    return b;",
-            "  }",
-            "}");
-    JavaFileObject numberChild = JavaFileObjects.forSourceLines("test.ChildNumberModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "class ChildNumberModule extends ParentModule<String, Number, Double> {",
-        "  @Provides Number provideNumber() { return 1; }",
-        "}");
-    JavaFileObject integerChild = JavaFileObjects.forSourceLines("test.ChildIntegerModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "class ChildIntegerModule extends ParentModule<StringBuilder, Integer, Float> {",
-        "  @Provides Integer provideInteger() { return 2; }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.C",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.List;",
-        "",
-        "@Component(modules={ChildNumberModule.class, ChildIntegerModule.class})",
-        "interface C {",
-        "  List<Number> numberList();",
-        "  List<Integer> integerList();",
-        "}");
-    JavaFileObject listBFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule_ProvideListBFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            "import java.util.List;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParentModule_ProvideListBFactory<A extends CharSequence,",
-            "    B, C extends Number & Comparable<C>> implements Factory<List<B>> {",
-            "  private final ParentModule<A, B, C> module;",
-            "  private final Provider<B> bProvider;",
-            "",
-            "  public ParentModule_ProvideListBFactory(",
-            "        ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    this.module = module;",
-            "    this.bProvider = bProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public List<B> get() {  ",
-            "    return provideListB(module, bProvider.get());",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
-            "      ParentModule_ProvideListBFactory<A, B, C>  create(",
-            "          ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    return new ParentModule_ProvideListBFactory<A, B, C>(module, bProvider);",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>> List<B>",
-            "      provideListB(ParentModule<A, B, C> instance, B b) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideListB(b), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    JavaFileObject bElementFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule_ProvideBElementFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParentModule_ProvideBElementFactory<A extends CharSequence,",
-            "    B, C extends Number & Comparable<C>> implements Factory<B> {",
-            "  private final ParentModule<A, B, C> module;",
-            "  private final Provider<B> bProvider;",
-            "",
-            "  public ParentModule_ProvideBElementFactory(",
-            "        ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    this.module = module;",
-            "    this.bProvider = bProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public B get() {  ",
-            "    return provideBElement(module, bProvider.get());",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
-            "      ParentModule_ProvideBElementFactory<A, B, C> create(",
-            "          ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    return new ParentModule_ProvideBElementFactory<A, B, C>(module, bProvider);",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
-            "      B provideBElement(",
-            "          ParentModule<A, B, C> instance, B b) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideBElement(b), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    JavaFileObject bEntryFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule_ProvideBEntryFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParentModule_ProvideBEntryFactory<A extends CharSequence,",
-            "    B, C extends Number & Comparable<C>> implements Factory<B>> {",
-            "  private final ParentModule<A, B, C> module;",
-            "  private final Provider<B> bProvider;",
-            "",
-            "  public ParentModule_ProvideBEntryFactory(",
-            "        ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    this.module = module;",
-            "    this.bProvider = bProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public B get() {  ",
-            "    return provideBEntry(module, bProvider.get());",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
-            "      ParentModule_ProvideBEntryFactory<A, B, C> create(",
-            "          ParentModule<A, B, C> module, Provider<B> bProvider) {",
-            "    return new ParentModule_ProvideBEntryFactory<A, B, C>(module, bProvider);",
-            "  }",
-            "",
-            "  public static <A extends CharSequence, B, C extends Number & Comparable<C>>",
-            "      B provideBEntry(",
-            "          ParentModule<A, B, C> instance, B b) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideBEntry(b), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    JavaFileObject numberFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ChildNumberModule_ProvideNumberFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ChildNumberModule_ProvideNumberFactory",
-            "    implements Factory<Number> {",
-            "  private final ChildNumberModule module;",
-            "",
-            "  public ChildNumberModule_ProvideNumberFactory(ChildNumberModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override",
-            "  public Number get() {  ",
-            "    return provideNumber(module);",
-            "  }",
-            "",
-            "  public static ChildNumberModule_ProvideNumberFactory create(",
-            "      ChildNumberModule module) {",
-            "    return new ChildNumberModule_ProvideNumberFactory(module);",
-            "  }",
-            "",
-            "  public static Number provideNumber(ChildNumberModule instance) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideNumber(), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    JavaFileObject integerFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ChildIntegerModule_ProvideIntegerFactory",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ChildIntegerModule_ProvideIntegerFactory",
-            "    implements Factory<Integer> {",
-            "  private final ChildIntegerModule module;",
-            "",
-            "  public ChildIntegerModule_ProvideIntegerFactory(ChildIntegerModule module) {",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  @Override",
-            "  public Integer get() {  ",
-            "    return provideInteger(module);",
-            "  }",
-            "",
-            "  public static ChildIntegerModule_ProvideIntegerFactory create(",
-            "      ChildIntegerModule module) {",
-            "    return new ChildIntegerModule_ProvideIntegerFactory(module);",
-            "  }",
-            "",
-            "  public static Integer provideInteger(ChildIntegerModule instance) {",
-            "    return Preconditions.checkNotNull(",
-            "        instance.provideInteger(), " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-    assertAbout(javaSources())
-        .that(ImmutableList.of(parent, numberChild, integerChild, component))
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(
-            listBFactory, bElementFactory, bEntryFactory, numberFactory, integerFactory);
-  }
-
-  @Test public void parameterizedModuleWithStaticProvidesMethodOfGenericType() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.ParameterizedModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.List;",
-            "import java.util.ArrayList;",
-            "import java.util.Map;",
-            "import java.util.HashMap;",
-            "",
-            "@Module abstract class ParameterizedModule<T> {",
-            "  @Provides List<T> provideListT() {",
-            "    return new ArrayList<>();",
-            "  }",
-            "",
-            "  @Provides static Map<String, Number> provideMapStringNumber() {",
-            "    return new HashMap<>();",
-            "  }",
-            "",
-            "  @Provides static Object provideNonGenericType() {",
-            "    return new Object();",
-            "  }",
-            "",
-            "  @Provides static String provideNonGenericTypeWithDeps(Object o) {",
-            "    return o.toString();",
-            "  }",
-            "}");
-
-    JavaFileObject provideMapStringNumberFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParameterizedModule_ProvideMapStringNumberFactory;",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            "import java.util.Map;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParameterizedModule_ProvideMapStringNumberFactory",
-            "    implements Factory<Map<String, Number>> {",
-            "  private static final ParameterizedModule_ProvideMapStringNumberFactory INSTANCE =",
-            "      new ParameterizedModule_ProvideMapStringNumberFactory();",
-            "",
-            "  @Override",
-            "  public Map<String, Number> get() {",
-            "    return provideMapStringNumber();",
-            "  }",
-            "",
-            "  public static ParameterizedModule_ProvideMapStringNumberFactory create() {",
-            "    return INSTANCE;",
-            "  }",
-            "",
-            "  public static Map<String, Number> provideMapStringNumber() {",
-            "    return Preconditions.checkNotNull(ParameterizedModule.provideMapStringNumber(),",
-            "        " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-
-    JavaFileObject provideNonGenericTypeFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParameterizedModule_ProvideNonGenericTypeFactory;",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParameterizedModule_ProvideNonGenericTypeFactory",
-            "    implements Factory<Object> {",
-            "  private static final ParameterizedModule_ProvideNonGenericTypeFactory INSTANCE = ",
-            "      new ParameterizedModule_ProvideNonGenericTypeFactory();",
-            "",
-            "  @Override",
-            "  public Object get() {",
-            "    return provideNonGenericType();",
-            "  }",
-            "",
-            "  public static ParameterizedModule_ProvideNonGenericTypeFactory create() {",
-            "    return INSTANCE;",
-            "  }",
-            "",
-            "  public static Object provideNonGenericType() {",
-            "    return Preconditions.checkNotNull(ParameterizedModule.provideNonGenericType(),",
-            "        " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-
-    JavaFileObject provideNonGenericTypeWithDepsFactory =
-        JavaFileObjects.forSourceLines(
-            "test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory;",
-            "package test;",
-            "",
-            "import dagger.internal.Factory;",
-            "import dagger.internal.Preconditions;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            GENERATED_ANNOTATION,
-            "public final class ParameterizedModule_ProvideNonGenericTypeWithDepsFactory",
-            "    implements Factory<String> {",
-            "  private final Provider<Object> oProvider;",
-            "",
-            "  public ParameterizedModule_ProvideNonGenericTypeWithDepsFactory(",
-            "      Provider<Object> oProvider) {",
-            "    this.oProvider = oProvider;",
-            "  }",
-            "",
-            "  @Override",
-            "  public String get() {",
-            "    return provideNonGenericTypeWithDeps(oProvider.get());",
-            "  }",
-            "",
-            "  public static ParameterizedModule_ProvideNonGenericTypeWithDepsFactory create(",
-            "      Provider<Object> oProvider) {",
-            "    return new ParameterizedModule_ProvideNonGenericTypeWithDepsFactory(oProvider);",
-            "  }",
-            "",
-            "  public static String provideNonGenericTypeWithDeps(Object o) {",
-            "    return Preconditions.checkNotNull(",
-            "        ParameterizedModule.provideNonGenericTypeWithDeps(o),",
-            "        " + NPE_FROM_PROVIDES_METHOD + ");",
-            "  }",
-            "}");
-
-    assertAbout(javaSource())
-        .that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(
-            provideMapStringNumberFactory,
-            provideNonGenericTypeFactory,
-            provideNonGenericTypeWithDepsFactory);
-  }
-
-  private static final JavaFileObject QUALIFIER_A =
-      JavaFileObjects.forSourceLines(
-          "test.QualifierA",
-          "package test;",
-          "",
-          "import javax.inject.Qualifier;",
-          "",
-          "@Qualifier @interface QualifierA {}");
-
-  private static final JavaFileObject QUALIFIER_B =
-      JavaFileObjects.forSourceLines(
-          "test.QualifierB",
-          "package test;",
-          "",
-          "import javax.inject.Qualifier;",
-          "",
-          "@Qualifier @interface QualifierB {}");
-
-  @Test
-  public void providesMethodMultipleQualifiersOnMethod() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides @QualifierA @QualifierB String provideString() {",
-        "    return \"foo\";",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void providesMethodMultipleQualifiersOnParameter() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides static String provideString(@QualifierA @QualifierB Object object) {",
-            "    return \"foo\";",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void providesMethodWildcardDependency() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides static String provideString(Provider<? extends Number> numberProvider) {",
-            "    return \"foo\";",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile, QUALIFIER_A, QUALIFIER_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Dagger does not support injecting Provider<T>, Lazy<T>, Producer<T>, or Produced<T> "
-                + "when T is a wildcard type such as ? extends java.lang.Number");
-  }
-
-  private static final JavaFileObject SCOPE_A =
-      JavaFileObjects.forSourceLines(
-          "test.ScopeA",
-          "package test;",
-          "",
-          "import javax.inject.Scope;",
-          "",
-          "@Scope @interface ScopeA {}");
-
-  private static final JavaFileObject SCOPE_B =
-      JavaFileObjects.forSourceLines(
-          "test.ScopeB",
-          "package test;",
-          "",
-          "import javax.inject.Scope;",
-          "",
-          "@Scope @interface ScopeB {}");
-
-  @Test
-  public void providesMethodMultipleScopes() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides",
-            "  @ScopeA",
-            "  @ScopeB",
-            "  String provideString() {",
-            "    return \"foo\";",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile, SCOPE_A, SCOPE_B);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cannot use more than one @Scope")
-        .inFile(moduleFile)
-        .onLineContaining("@ScopeA");
-    assertThat(compilation)
-        .hadErrorContaining("cannot use more than one @Scope")
-        .inFile(moduleFile)
-        .onLineContaining("@ScopeB");
-  }
-
-  @Test public void providerDependsOnProduced() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.producers.Producer;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String provideString(Producer<Integer> producer) {",
-        "    return \"foo\";",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Producer may only be injected in @Produces methods");
-  }
-
-  @Test public void providerDependsOnProducer() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.producers.Produced;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String provideString(Produced<Integer> produced) {",
-        "    return \"foo\";",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Produced may only be injected in @Produces methods");
-  }
-
-  @Test
-  public void proxyMethodsConflictWithOtherFactoryMethods() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static int get() { return 1; }",
-            "",
-            "  @Provides",
-            "  static boolean create() { return true; }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(module);
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.TestModule_GetFactory")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.TestModule_GetFactory",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class TestModule_GetFactory implements Factory<Integer> {",
-                "  @Override",
-                "  public Integer get() {",
-                "    return proxyGet();",
-                "  }",
-                "",
-                "  public static TestModule_GetFactory create() {",
-                "    return INSTANCE;",
-                "  }",
-                "",
-                "  public static int proxyGet() {",
-                "    return TestModule.get();",
-                "  }",
-                "}"));
-
-    assertThat(compilation)
-        .generatedSourceFile("test.TestModule_CreateFactory")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.TestModule_CreateFactory",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "public final class TestModule_CreateFactory implements Factory<Boolean> {",
-                "  @Override",
-                "  public Boolean get() {",
-                "    return proxyCreate();",
-                "  }",
-                "",
-                "  public static TestModule_CreateFactory create() {",
-                "    return INSTANCE;",
-                "  }",
-                "",
-                "  public static boolean proxyCreate() {",
-                "    return TestModule.create();",
-                "  }",
-                "}"));
-  }
-
-  private static final String BINDS_METHOD = "@Binds abstract Foo bindFoo(FooImpl impl);";
-  private static final String MULTIBINDS_METHOD = "@Multibinds abstract Set<Foo> foos();";
-  private static final String STATIC_PROVIDES_METHOD =
-      "@Provides static Bar provideBar() { return new Bar(); }";
-  private static final String INSTANCE_PROVIDES_METHOD =
-      "@Provides Baz provideBaz() { return new Baz(); }";
-  private static final String SOME_ABSTRACT_METHOD = "abstract void blah();";
-
-  @Test
-  public void bindsWithInstanceProvides() {
-    Compilation compilation = compileMethodCombination(BINDS_METHOD, INSTANCE_PROVIDES_METHOD);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "A @Module may not contain both non-static and abstract binding methods");
-  }
-
-  @Test
-  public void multibindsWithInstanceProvides() {
-    Compilation compilation = compileMethodCombination(MULTIBINDS_METHOD, INSTANCE_PROVIDES_METHOD);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "A @Module may not contain both non-static and abstract binding methods");
-  }
-
-  @Test
-  public void bindsWithStaticProvides() {
-    assertThat(compileMethodCombination(BINDS_METHOD, STATIC_PROVIDES_METHOD)).succeeded();
-  }
-
-  @Test
-  public void bindsWithMultibinds() {
-    assertThat(compileMethodCombination(BINDS_METHOD, MULTIBINDS_METHOD)).succeeded();
-  }
-
-  @Test
-  public void multibindsWithStaticProvides() {
-    assertThat(compileMethodCombination(MULTIBINDS_METHOD, STATIC_PROVIDES_METHOD)).succeeded();
-  }
-
-  @Test
-  public void instanceProvidesWithAbstractMethod() {
-    assertThat(compileMethodCombination(INSTANCE_PROVIDES_METHOD, SOME_ABSTRACT_METHOD))
-        .succeeded();
-  }
-
-  private Compilation compileMethodCombination(String... methodLines) {
-    JavaFileObject fooFile =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "interface Foo {}");
-    JavaFileObject fooImplFile =
-        JavaFileObjects.forSourceLines(
-            "test.FooImpl",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class FooImpl implements Foo {",
-            "  @Inject FooImpl() {}",
-            "}");
-    JavaFileObject barFile =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "final class Bar {}");
-    JavaFileObject bazFile =
-        JavaFileObjects.forSourceLines(
-            "test.Baz",
-            "package test;",
-            "",
-            "final class Baz {}");
-
-    ImmutableList<String> moduleLines =
-        new ImmutableList.Builder<String>()
-            .add(
-                "package test;",
-                "",
-                "import dagger.Binds;",
-                "import dagger.Module;",
-                "import dagger.Provides;",
-                "import dagger.multibindings.Multibinds;",
-                "import java.util.Set;",
-                "",
-                "@Module abstract class TestModule {")
-            .add(methodLines)
-            .add("}")
-            .build();
-
-    JavaFileObject bindsMethodAndInstanceProvidesMethodModuleFile =
-        JavaFileObjects.forSourceLines("test.TestModule", moduleLines);
-    return daggerCompiler()
-        .compile(
-            fooFile, fooImplFile, barFile, bazFile, bindsMethodAndInstanceProvidesMethodModuleFile);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ModuleValidationTest.java b/javatests/dagger/internal/codegen/ModuleValidationTest.java
deleted file mode 100644
index 649649a..0000000
--- a/javatests/dagger/internal/codegen/ModuleValidationTest.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2016 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.lang.annotation.Annotation;
-import java.util.Arrays;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public final class ModuleValidationTest {
-
-  @Parameterized.Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(new Object[][] {{ModuleType.MODULE}, {ModuleType.PRODUCER_MODULE}});
-  }
-
-  private enum ModuleType {
-    MODULE(Module.class),
-    PRODUCER_MODULE(ProducerModule.class),
-    ;
-
-    private final Class<? extends Annotation> annotation;
-
-    ModuleType(Class<? extends Annotation> annotation) {
-      this.annotation = annotation;
-    }
-
-    String annotationWithSubcomponent(String subcomponent) {
-      return String.format("@%s(subcomponents = %s)", annotation.getSimpleName(), subcomponent);
-    }
-
-    String importStatement() {
-      return String.format("import %s;", annotation.getName());
-    }
-
-    String simpleName() {
-      return annotation.getSimpleName();
-    }
-  }
-
-  private final ModuleType moduleType;
-
-  public ModuleValidationTest(ModuleType moduleType) {
-    this.moduleType = moduleType;
-  }
-
-  @Test
-  public void moduleSubcomponents_notASubcomponent() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("NotASubcomponent.class"),
-            "class TestModule {}");
-    JavaFileObject notASubcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.NotASubcomponent", "package test;", "", "class NotASubcomponent {}");
-    Compilation compilation = daggerCompiler().compile(module, notASubcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.NotASubcomponent is not a @Subcomponent or @ProductionSubcomponent")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_listsSubcomponentBuilder() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("Sub.Builder.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Sub build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Sub.Builder is a @Subcomponent.Builder. Did you mean to use test.Sub?")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_listsSubcomponentFactory() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("Sub.Factory.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  @Subcomponent.Factory",
-            "  interface Factory {",
-            "    Sub creator();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Sub.Factory is a @Subcomponent.Factory. Did you mean to use test.Sub?")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_listsProductionSubcomponentBuilder() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("Sub.Builder.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent",
-            "interface Sub {",
-            "  @ProductionSubcomponent.Builder",
-            "  interface Builder {",
-            "    Sub build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Sub.Builder is a @ProductionSubcomponent.Builder. Did you mean to use test.Sub?")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_listsProductionSubcomponentFactory() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("Sub.Factory.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent",
-            "interface Sub {",
-            "  @ProductionSubcomponent.Factory",
-            "  interface Factory {",
-            "    Sub create();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Sub.Factory is a @ProductionSubcomponent.Factory. Did you mean to use test.Sub?")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_noSubcomponentCreator() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("NoBuilder.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.NoBuilder",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface NoBuilder {}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.NoBuilder doesn't have a @Subcomponent.Builder or @Subcomponent.Factory, which "
-                + "is required when used with @"
-                + moduleType.simpleName()
-                + ".subcomponents")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponents_noProductionSubcomponentCreator() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "",
-            moduleType.annotationWithSubcomponent("NoBuilder.class"),
-            "class TestModule {}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.NoBuilder",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent",
-            "interface NoBuilder {}");
-    Compilation compilation = daggerCompiler().compile(module, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.NoBuilder doesn't have a @ProductionSubcomponent.Builder or "
-                + "@ProductionSubcomponent.Factory, which is required when used with @"
-                + moduleType.simpleName()
-                + ".subcomponents")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void moduleSubcomponentsAreTypes() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module(subcomponents = int.class)",
-            "class TestModule {}");
-    Compilation compilation = daggerCompiler().compile(module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("int is not a valid subcomponent type")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void tooManyAnnotations() {
-    assertThatModuleMethod(
-            "@BindsOptionalOf @Multibinds abstract Set<Object> tooManyAnnotations();")
-        .hasError("is annotated with more than one of");
-  }
-
-  @Test
-  public void invalidIncludedModule() {
-    JavaFileObject badModule =
-        JavaFileObjects.forSourceLines(
-            "test.BadModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "abstract class BadModule {",
-            "  @Binds abstract Object noParameters();",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.IncludesBadModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module(includes = BadModule.class)",
-            "abstract class IncludesBadModule {}");
-    assertThat(daggerCompiler().compile(badModule, module))
-        .hadErrorContaining("test.BadModule has errors")
-        .inFile(module)
-        .onLine(5);
-  }
-
-  @Test
-  public void scopeOnModule() {
-    JavaFileObject badModule =
-        JavaFileObjects.forSourceLines(
-            "test.BadModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Module",
-            "interface BadModule {}");
-    Compilation compilation = daggerCompiler().compile(badModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Modules cannot be scoped")
-        .inFile(badModule)
-        .onLineContaining("@Singleton");
-  }
-
-  @Test
-  public void moduleIncludesSelfCycle() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            moduleType.importStatement(),
-            "import dagger.Provides;",
-            "",
-            String.format("@%s(", moduleType.simpleName()),
-            "  includes = {",
-            "      TestModule.class, // first",
-            "      OtherModule.class,",
-            "      TestModule.class, // second",
-            "  }",
-            ")",
-            "class TestModule {",
-            "  @Provides int i() { return 0; }",
-            "}");
-
-    JavaFileObject otherModule =
-        JavaFileObjects.forSourceLines(
-            "test.OtherModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "class OtherModule {}");
-
-    Compilation compilation = daggerCompiler().compile(module, otherModule);
-    assertThat(compilation).failed();
-    String error = String.format("@%s cannot include themselves", moduleType.simpleName());
-    assertThat(compilation).hadErrorContaining(error).inFile(module).onLineContaining("Module(");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MultibindingTest.java b/javatests/dagger/internal/codegen/MultibindingTest.java
deleted file mode 100644
index 2bf9494..0000000
--- a/javatests/dagger/internal/codegen/MultibindingTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2016 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MultibindingTest {
-
-  @Test
-  public void providesWithTwoMultibindingAnnotations_failsToCompile() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.MultibindingModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "@Module",
-            "class MultibindingModule {",
-            "  @Provides @IntoSet @IntoMap Integer provideInt() { ",
-            "    return 1;",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Provides methods cannot have more than one multibinding annotation")
-        .inFile(module)
-        .onLine(10);
-  }
-
-  @Test
-  public void appliedOnInvalidMethods_failsToCompile() {
-    JavaFileObject someType =
-        JavaFileObjects.forSourceLines(
-            "test.SomeType",
-            "package test;",
-            "",
-            "import java.util.Set;",
-            "import java.util.Map;",
-            "import dagger.Component;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import dagger.multibindings.IntoMap;",
-            "",
-            "interface SomeType {",
-            "  @IntoSet Set<Integer> ints();",
-            "  @ElementsIntoSet Set<Double> doubles();",
-            "  @IntoMap Map<Integer, Double> map();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(someType);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Multibinding annotations may only be on @Provides, @Produces, or @Binds methods")
-        .inFile(someType)
-        .onLineContaining("ints();");
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Multibinding annotations may only be on @Provides, @Produces, or @Binds methods")
-        .inFile(someType)
-        .onLineContaining("doubles();");
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Multibinding annotations may only be on @Provides, @Produces, or @Binds methods")
-        .inFile(someType)
-        .onLineContaining("map();");
-  }
-
-  @Test
-  public void concreteBindingForMultibindingAlias() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.Collections;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "@Module",
-            "class TestModule {",
-            "  @Provides",
-            "  Map<String, Provider<String>> mapOfStringToProviderOfString() {",
-            "    return Collections.emptyMap();",
-            "  }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Map<String, String> mapOfStringToString();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Map<java.lang.String,java.lang.String> "
-                + "cannot be provided without an @Provides-annotated method")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void produceConcreteSet_andRequestSetOfProduced() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import java.util.Collections;",
-            "import java.util.Set;",
-            "",
-            "@ProducerModule",
-            "class TestModule {",
-            "  @Produces",
-            "  Set<String> setOfString() {",
-            "    return Collections.emptySet();",
-            "  }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.BindsInstance;",
-            "import dagger.producers.Produced;",
-            "import dagger.producers.Production;",
-            "import dagger.producers.ProductionComponent;",
-            "import java.util.concurrent.Executor;",
-            "import java.util.Set;",
-            "",
-            "@ProductionComponent(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  ListenableFuture<Set<Produced<String>>> setOfProduced();",
-            "",
-            "  @ProductionComponent.Builder",
-            "  interface Builder {",
-            "    @BindsInstance Builder executor(@Production Executor executor);",
-            "    TestComponent build();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Set<dagger.producers.Produced<java.lang.String>> "
-                + "cannot be provided without an @Provides- or @Produces-annotated method")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void provideExplicitSetInParent_AndMultibindingContributionInChild() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Set;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Set<String> set();",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.HashSet;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides",
-            "  Set<String> set() {",
-            "    return new HashSet();",
-            "  }",
-            "}");
-
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  Set<String> set();",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "class ChildModule {",
-            "  @Provides",
-            "  @IntoSet",
-            "  String setContribution() {",
-            "    return new String();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, parentModule, child, childModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("incompatible bindings or declarations")
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/MultibindsValidationTest.java b/javatests/dagger/internal/codegen/MultibindsValidationTest.java
deleted file mode 100644
index e5603a4..0000000
--- a/javatests/dagger/internal/codegen/MultibindsValidationTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2016 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 dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
-
-import com.google.common.collect.ImmutableList;
-import dagger.Module;
-import dagger.producers.ProducerModule;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import javax.inject.Qualifier;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MultibindsValidationTest {
-
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return ImmutableList.copyOf(new Object[][] {{Module.class}, {ProducerModule.class}});
-  }
-
-  private final String moduleDeclaration;
-
-  public MultibindsValidationTest(Class<? extends Annotation> moduleAnnotation) {
-    moduleDeclaration = "@" + moduleAnnotation.getCanonicalName() + " abstract class %s { %s }";
-  }
-
-  @Test
-  public void notWithinModule() {
-    assertThatMethodInUnannotatedClass("@Multibinds abstract Set<Object> emptySet();")
-        .hasError("@Multibinds methods can only be present within a @Module or @ProducerModule");
-  }
-
-  @Test
-  public void voidMethod() {
-    assertThatModuleMethod("@Multibinds abstract void voidMethod();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void primitiveMethod() {
-    assertThatModuleMethod("@Multibinds abstract int primitive();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void rawMap() {
-    assertThatModuleMethod("@Multibinds abstract Map rawMap();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void wildcardMap() {
-    assertThatModuleMethod("@Multibinds abstract Map<?, ?> wildcardMap();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void providerMap() {
-    assertThatModuleMethod("@Multibinds abstract Map<String, Provider<Object>> providerMap();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void producerMap() {
-    assertThatModuleMethod("@Multibinds abstract Map<String, Producer<Object>> producerMap();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void producedMap() {
-    assertThatModuleMethod("@Multibinds abstract Map<String, Produced<Object>> producedMap();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void rawSet() {
-    assertThatModuleMethod("@Multibinds abstract Set rawSet();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void wildcardSet() {
-    assertThatModuleMethod("@Multibinds abstract Set<?> wildcardSet();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void providerSet() {
-    assertThatModuleMethod("@Multibinds abstract Set<Provider<Object>> providerSet();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void producerSet() {
-    assertThatModuleMethod("@Multibinds abstract Set<Producer<Object>> producerSet();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void producedSet() {
-    assertThatModuleMethod("@Multibinds abstract Set<Produced<Object>> producedSet();")
-        .withDeclaration(moduleDeclaration)
-        .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
-  }
-
-  @Test
-  public void overqualifiedSet() {
-    assertThatModuleMethod(
-            "@Multibinds @SomeQualifier @OtherQualifier "
-                + "abstract Set<Object> tooManyQualifiersSet();")
-        .withDeclaration(moduleDeclaration)
-        .importing(SomeQualifier.class, OtherQualifier.class)
-        .hasError("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void overqualifiedMap() {
-    assertThatModuleMethod(
-            "@Multibinds @SomeQualifier @OtherQualifier "
-                + "abstract Map<String, Object> tooManyQualifiersMap();")
-        .withDeclaration(moduleDeclaration)
-        .importing(SomeQualifier.class, OtherQualifier.class)
-        .hasError("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void hasParameters() {
-    assertThatModuleMethod("@Multibinds abstract Set<String> parameters(Object param);")
-        .hasError("@Multibinds methods cannot have parameters");
-  }
-
-  @Qualifier
-  public @interface SomeQualifier {}
-
-  @Qualifier
-  public @interface OtherQualifier {}
-}
diff --git a/javatests/dagger/internal/codegen/MultipleRequestTest.java b/javatests/dagger/internal/codegen/MultipleRequestTest.java
deleted file mode 100644
index a5514ca..0000000
--- a/javatests/dagger/internal/codegen/MultipleRequestTest.java
+++ /dev/null
@@ -1,126 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MultipleRequestTest {
-  private static final JavaFileObject DEP_FILE = JavaFileObjects.forSourceLines("test.Dep",
-      "package test;",
-      "",
-      "import javax.inject.Inject;",
-      "",
-      "class Dep {",
-      "  @Inject Dep() {}",
-      "}");
-
-  @Test public void multipleRequests_constructor() {
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                DEP_FILE,
-                JavaFileObjects.forSourceLines(
-                    "test.ConstructorInjectsMultiple",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "class ConstructorInjectsMultiple {",
-                    "  @Inject ConstructorInjectsMultiple(Dep d1, Dep d2) {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.SimpleComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component",
-                    "interface SimpleComponent {",
-                    "  ConstructorInjectsMultiple get();",
-                    "}"));
-    assertThat(compilation).succeeded();
-  }
-
-  @Test public void multipleRequests_field() {
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                DEP_FILE,
-                JavaFileObjects.forSourceLines(
-                    "test.FieldInjectsMultiple",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "class FieldInjectsMultiple {",
-                    "  @Inject Dep d1;",
-                    "  @Inject Dep d2;",
-                    "  @Inject FieldInjectsMultiple() {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.SimpleComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component",
-                    "interface SimpleComponent {",
-                    "  FieldInjectsMultiple get();",
-                    "}"));
-    assertThat(compilation).succeeded();
-  }
-
-  @Test public void multipleRequests_providesMethod() {
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                DEP_FILE,
-                JavaFileObjects.forSourceLines(
-                    "test.FieldInjectsMultiple",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "",
-                    "@Module",
-                    "class SimpleModule {",
-                    "  @Provides Object provide(Dep d1, Dep d2) {",
-                    "    return null;",
-                    "  }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.SimpleComponent",
-                    "package test;",
-                    "",
-                    "import dagger.Component;",
-                    "",
-                    "@Component(modules = SimpleModule.class)",
-                    "interface SimpleComponent {",
-                    "  Object get();",
-                    "}"));
-    assertThat(compilation).succeeded();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/NullableBindingValidationTest.java b/javatests/dagger/internal/codegen/NullableBindingValidationTest.java
deleted file mode 100644
index 24d5636..0000000
--- a/javatests/dagger/internal/codegen/NullableBindingValidationTest.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.NullableBindingValidator.nullableToNonNullable;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NullableBindingValidationTest {
-  private static final JavaFileObject NULLABLE =
-      JavaFileObjects.forSourceLines(
-          "test.Nullable", // force one-string-per-line format
-          "package test;",
-          "",
-          "public @interface Nullable {}");
-
-  @Test public void nullCheckForConstructorParameters() {
-    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A(String string) {}",
-        "}");
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class TestModule {",
-        "  @Nullable @Provides String provideString() { return null; }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "  A a();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@test.Nullable @Provides String test.TestModule.provideString()"));
-
-    // but if we disable the validation, then it compiles fine.
-    Compilation compilation2 =
-        javac()
-            .withOptions("-Adagger.nullableValidation=WARNING")
-            .withProcessors(new ComponentProcessor())
-            .compile(NULLABLE, a, module, component);
-    assertThat(compilation2).succeeded();
-  }
-
-  @Test public void nullCheckForMembersInjectParam() {
-    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject A() {}",
-        "  @Inject void register(String string) {}",
-        "}");
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class TestModule {",
-        "  @Nullable @Provides String provideString() { return null; }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "  A a();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@test.Nullable @Provides String test.TestModule.provideString()"));
-
-    // but if we disable the validation, then it compiles fine.
-    Compilation compilation2 =
-        javac()
-            .withOptions("-Adagger.nullableValidation=WARNING")
-            .withProcessors(new ComponentProcessor())
-            .compile(NULLABLE, a, module, component);
-    assertThat(compilation2).succeeded();
-  }
-
-  @Test public void nullCheckForVariable() {
-    JavaFileObject a = JavaFileObjects.forSourceLines("test.A",
-        "package test;",
-        "",
-        "import javax.inject.Inject;",
-        "",
-        "final class A {",
-        "  @Inject String string;",
-        "  @Inject A() {}",
-        "}");
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class TestModule {",
-        "  @Nullable @Provides String provideString() { return null; }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "  A a();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@test.Nullable @Provides String test.TestModule.provideString()"));
-
-    // but if we disable the validation, then it compiles fine.
-    Compilation compilation2 =
-        javac()
-            .withOptions("-Adagger.nullableValidation=WARNING")
-            .withProcessors(new ComponentProcessor())
-            .compile(NULLABLE, a, module, component);
-    assertThat(compilation2).succeeded();
-  }
-
-  @Test public void nullCheckForComponentReturn() {
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Provides;",
-        "import javax.inject.Inject;",
-        "",
-        "@dagger.Module",
-        "final class TestModule {",
-        "  @Nullable @Provides String provideString() { return null; }",
-        "}");
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component(modules = TestModule.class)",
-        "interface TestComponent {",
-        "  String string();",
-        "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@test.Nullable @Provides String test.TestModule.provideString()"));
-
-    // but if we disable the validation, then it compiles fine.
-    Compilation compilation2 =
-        javac()
-            .withOptions("-Adagger.nullableValidation=WARNING")
-            .withProcessors(new ComponentProcessor())
-            .compile(NULLABLE, module, component);
-    assertThat(compilation2).succeeded();
-  }
-
-  @Test
-  public void nullCheckForOptionalInstance() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import javax.inject.Inject;",
-            "",
-            "final class A {",
-            "  @Inject A(Optional<String> optional) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "@dagger.Module",
-            "abstract class TestModule {",
-            "  @Nullable @Provides static String provideString() { return null; }",
-            "  @BindsOptionalOf abstract String optionalString();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@test.Nullable @Provides String test.TestModule.provideString()"));
-  }
-
-  @Test
-  public void nullCheckForOptionalProvider() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class A {",
-            "  @Inject A(Optional<Provider<String>> optional) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "@dagger.Module",
-            "abstract class TestModule {",
-            "  @Nullable @Provides static String provideString() { return null; }",
-            "  @BindsOptionalOf abstract String optionalString();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void nullCheckForOptionalLazy() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import dagger.Lazy;",
-            "import javax.inject.Inject;",
-            "",
-            "final class A {",
-            "  @Inject A(Optional<Lazy<String>> optional) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "@dagger.Module",
-            "abstract class TestModule {",
-            "  @Nullable @Provides static String provideString() { return null; }",
-            "  @BindsOptionalOf abstract String optionalString();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void nullCheckForOptionalProviderOfLazy() {
-    JavaFileObject a =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import dagger.Lazy;",
-            "import javax.inject.Inject;",
-            "import javax.inject.Provider;",
-            "",
-            "final class A {",
-            "  @Inject A(Optional<Provider<Lazy<String>>> optional) {}",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Provides;",
-            "import javax.inject.Inject;",
-            "",
-            "@dagger.Module",
-            "abstract class TestModule {",
-            "  @Nullable @Provides static String provideString() { return null; }",
-            "  @BindsOptionalOf abstract String optionalString();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  A a();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(NULLABLE, a, module, component);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test
-  public void moduleValidation() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "abstract class TestModule {",
-            "  @Provides @Nullable static String nullableString() { return null; }",
-            "  @Binds abstract Object object(String string);",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(module, NULLABLE);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            nullableToNonNullable(
-                "java.lang.String",
-                "@Provides @test.Nullable String test.TestModule.nullableString()"));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java b/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java
deleted file mode 100644
index b765166..0000000
--- a/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.compilerWithOptions;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class OptionalBindingRequestFulfillmentTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public OptionalBindingRequestFulfillmentTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void inlinedOptionalBindings() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.BindsOptionalOf;",
-            "import other.Maybe;",
-            "import other.DefinitelyNot;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @BindsOptionalOf Maybe maybe();",
-            "  @BindsOptionalOf DefinitelyNot definitelyNot();",
-            "}");
-    JavaFileObject maybe =
-        JavaFileObjects.forSourceLines(
-            "other.Maybe",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "public class Maybe {",
-            "  @Module",
-            "  public static class MaybeModule {",
-            "    @Provides static Maybe provideMaybe() { return new Maybe(); }",
-            "  }",
-            "}");
-    JavaFileObject definitelyNot =
-        JavaFileObjects.forSourceLines(
-            "other.DefinitelyNot",
-            "package other;",
-            "",
-            "public class DefinitelyNot {}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import dagger.Component;",
-            "import dagger.Lazy;",
-            "import javax.inject.Provider;",
-            "import other.Maybe;",
-            "import other.DefinitelyNot;",
-            "",
-            "@Component(modules = {TestModule.class, Maybe.MaybeModule.class})",
-            "interface TestComponent {",
-            "  Optional<Maybe> maybe();",
-            "  Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe();",
-            "  Optional<DefinitelyNot> definitelyNot();",
-            "  Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerTestComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import com.google.common.base.Optional;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private volatile Provider<Maybe> provideMaybeProvider;",
-                "",
-                "  private Provider<Maybe> getMaybeProvider() {",
-                "    Object local = provideMaybeProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      provideMaybeProvider = (Provider<Maybe>) local;",
-                "    }",
-                "    return (Provider<Maybe>) local;",
-                "  }")
-            .addLines(
-                "  @Override",
-                "  public Optional<Maybe> maybe() {",
-                "    return Optional.of(",
-                "        Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() {",
-                "    return Optional.of(ProviderOfLazy.create(")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "        Maybe_MaybeModule_ProvideMaybeFactory.create()));")
-            .addLinesIn(
-                FAST_INIT_MODE, //
-                "        getMaybeProvider()));")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public Optional<DefinitelyNot> definitelyNot() {",
-                "    return Optional.<DefinitelyNot>absent();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Optional<Provider<Lazy<DefinitelyNot>>>",
-                "      providerOfLazyOfDefinitelyNot() {",
-                "    return Optional.<Provider<Lazy<DefinitelyNot>>>absent();",
-                "  }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "          return (T) Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe();",
-                "        default:",
-                "          throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}")
-            .build();
-    Compilation compilation =
-        compilerWithOptions(
-                compilerMode
-                , CompilerMode.JAVA7
-                )
-            .compile(module, maybe, definitelyNot, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void requestForFuture() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.BindsOptionalOf;",
-            "import other.Maybe;",
-            "import other.DefinitelyNot;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @BindsOptionalOf Maybe maybe();",
-            "  @BindsOptionalOf DefinitelyNot definitelyNot();",
-            "}");
-    JavaFileObject maybe =
-        JavaFileObjects.forSourceLines(
-            "other.Maybe",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "public class Maybe {",
-            "  @Module",
-            "  public static class MaybeModule {",
-            "    @Provides static Maybe provideMaybe() { return new Maybe(); }",
-            "  }",
-            "}");
-    JavaFileObject definitelyNot =
-        JavaFileObjects.forSourceLines(
-            "other.DefinitelyNot",
-            "package other;",
-            "",
-            "public class DefinitelyNot {}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionComponent;",
-            "import javax.inject.Provider;",
-            "import other.Maybe;",
-            "import other.DefinitelyNot;",
-            "",
-            "@ProductionComponent(modules = {TestModule.class, Maybe.MaybeModule.class})",
-            "interface TestComponent {",
-            "  ListenableFuture<Optional<Maybe>> maybe();",
-            "  ListenableFuture<Optional<DefinitelyNot>> definitelyNot();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.common.base.Optional;",
-            "import dagger.producers.internal.CancellationListener;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent, CancellationListener {",
-            "  @Override",
-            "  public ListenableFuture<Optional<Maybe>> maybe() {",
-            "    return Futures.immediateFuture(",
-            "        Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe()));",
-            "  }",
-            "",
-            "  @Override",
-            "  public ListenableFuture<Optional<DefinitelyNot>> definitelyNot() {",
-            "    return Futures.immediateFuture(Optional.<DefinitelyNot>absent());",
-
-            "  }",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {}",
-            "}");
-
-    Compilation compilation =
-        compilerWithOptions(
-                compilerMode
-                , CompilerMode.JAVA7
-                )
-            .compile(module, maybe, definitelyNot, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/OptionalBindingTest.java b/javatests/dagger/internal/codegen/OptionalBindingTest.java
deleted file mode 100644
index 1755101..0000000
--- a/javatests/dagger/internal/codegen/OptionalBindingTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class OptionalBindingTest {
-  @Test
-  public void provideExplicitOptionalInParent_AndBindsOptionalOfInChild() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Optional;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Optional<String> optional();",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import java.util.Optional;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides",
-            "  Optional<String> optional() {",
-            "    return Optional.of(new String());",
-            "  }",
-            "}");
-
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Optional;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface Child {",
-            "  Optional<String> optional();",
-            "}");
-    JavaFileObject childModule =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface ChildModule {",
-            "  @BindsOptionalOf",
-            "  String optionalString();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(parent, parentModule, child, childModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Optional<java.lang.String> is bound multiple times")
-        .inFile(parent)
-        .onLineContaining("interface Parent");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java b/javatests/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java
deleted file mode 100644
index 0b6ef8f..0000000
--- a/javatests/dagger/internal/codegen/ProducerModuleFactoryGeneratorTest.java
+++ /dev/null
@@ -1,522 +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.
- */
-
-// TODO(beder): Merge the error-handling tests with the ModuleFactoryGeneratorTest.
-package dagger.internal.codegen;
-
-import static com.google.common.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
-import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatProductionModuleMethod;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.lang.annotation.Retention;
-import javax.inject.Qualifier;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ProducerModuleFactoryGeneratorTest {
-
-  @Test public void producesMethodNotInModule() {
-    assertThatMethodInUnannotatedClass("@Produces String produceString() { return null; }")
-        .hasError("@Produces methods can only be present within a @ProducerModule");
-  }
-
-  @Test public void producesMethodAbstract() {
-    assertThatProductionModuleMethod("@Produces abstract String produceString();")
-        .hasError("@Produces methods cannot be abstract");
-  }
-
-  @Test public void producesMethodPrivate() {
-    assertThatProductionModuleMethod("@Produces private String produceString() { return null; }")
-        .hasError("@Produces methods cannot be private");
-  }
-
-  @Test public void producesMethodReturnVoid() {
-    assertThatProductionModuleMethod("@Produces void produceNothing() {}")
-        .hasError("@Produces methods must return a value (not void)");
-  }
-
-  @Test
-  public void producesProvider() {
-    assertThatProductionModuleMethod("@Produces Provider<String> produceProvider() {}")
-        .hasError("@Produces methods must not return framework types");
-  }
-
-  @Test
-  public void producesLazy() {
-    assertThatProductionModuleMethod("@Produces Lazy<String> produceLazy() {}")
-        .hasError("@Produces methods must not return framework types");
-  }
-
-  @Test
-  public void producesMembersInjector() {
-    assertThatProductionModuleMethod(
-            "@Produces MembersInjector<String> produceMembersInjector() {}")
-        .hasError("@Produces methods must not return framework types");
-  }
-
-  @Test
-  public void producesProducer() {
-    assertThatProductionModuleMethod("@Produces Producer<String> produceProducer() {}")
-        .hasError("@Produces methods must not return framework types");
-  }
-
-  @Test
-  public void producesProduced() {
-    assertThatProductionModuleMethod("@Produces Produced<String> produceProduced() {}")
-        .hasError("@Produces methods must not return framework types");
-  }
-
-  @Test public void producesMethodReturnRawFuture() {
-    assertThatProductionModuleMethod("@Produces ListenableFuture produceRaw() {}")
-        .importing(ListenableFuture.class)
-        .hasError("@Produces methods cannot return a raw ListenableFuture");
-  }
-
-  @Test public void producesMethodReturnWildcardFuture() {
-    assertThatProductionModuleMethod("@Produces ListenableFuture<?> produceRaw() {}")
-        .importing(ListenableFuture.class)
-        .hasError(
-            "@Produces methods can return only a primitive, an array, a type variable, "
-                + "a declared type, or a ListenableFuture of one of those types");
-  }
-
-  @Test public void producesMethodWithTypeParameter() {
-    assertThatProductionModuleMethod("@Produces <T> String produceString() { return null; }")
-        .hasError("@Produces methods may not have type parameters");
-  }
-
-  @Test public void producesMethodSetValuesWildcard() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet Set<?> produceWildcard() { return null; }")
-        .hasError(
-            "@Produces methods can return only a primitive, an array, a type variable, "
-                + "a declared type, or a ListenableFuture of one of those types");
-  }
-
-  @Test public void producesMethodSetValuesRawSet() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet Set produceSomething() { return null; }")
-        .hasError("@Produces methods annotated with @ElementsIntoSet cannot return a raw Set");
-  }
-
-  @Test public void producesMethodSetValuesNotASet() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet List<String> produceStrings() { return null; }")
-        .hasError(
-            "@Produces methods of type set values must return a Set or ListenableFuture of Set");
-  }
-
-  @Test public void producesMethodSetValuesWildcardInFuture() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet "
-                + "ListenableFuture<Set<?>> produceWildcard() { return null; }")
-        .importing(ListenableFuture.class)
-        .hasError(
-            "@Produces methods can return only a primitive, an array, a type variable, "
-                + "a declared type, or a ListenableFuture of one of those types");
-  }
-
-  @Test public void producesMethodSetValuesFutureRawSet() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet ListenableFuture<Set> produceSomething() { return null; }")
-        .importing(ListenableFuture.class)
-        .hasError("@Produces methods annotated with @ElementsIntoSet cannot return a raw Set");
-  }
-
-  @Test public void producesMethodSetValuesFutureNotASet() {
-    assertThatProductionModuleMethod(
-            "@Produces @ElementsIntoSet "
-                + "ListenableFuture<List<String>> produceStrings() { return null; }")
-        .importing(ListenableFuture.class)
-        .hasError(
-            "@Produces methods of type set values must return a Set or ListenableFuture of Set");
-  }
-
-  @Test public void multipleProducesMethodsWithSameName() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "",
-        "@ProducerModule",
-        "final class TestModule {",
-        "  @Produces Object produce(int i) {",
-        "    return i;",
-        "  }",
-        "",
-        "  @Produces String produce() {",
-        "    return \"\";",
-        "  }",
-        "}");
-    String errorMessage =
-        "Cannot have more than one binding method with the same name in a single module";
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(errorMessage).inFile(moduleFile).onLine(8);
-    assertThat(compilation).hadErrorContaining(errorMessage).inFile(moduleFile).onLine(12);
-  }
-
-  @Test
-  public void producesMethodThrowsThrowable() {
-    assertThatProductionModuleMethod("@Produces int produceInt() throws Throwable { return 0; }")
-        .hasError(
-            "@Produces methods may only throw unchecked exceptions or exceptions subclassing "
-                + "Exception");
-  }
-
-  @Test public void producesMethodWithScope() {
-    assertThatProductionModuleMethod("@Produces @Singleton String str() { return \"\"; }")
-        .hasError("@Produces methods cannot be scoped");
-  }
-
-  @Test
-  public void privateModule() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "",
-        "final class Enclosing {",
-        "  @ProducerModule private static final class PrivateModule {",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Modules cannot be private")
-        .inFile(moduleFile)
-        .onLine(6);
-  }
-
-  @Test
-  public void enclosedInPrivateModule() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.Enclosing",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "",
-        "final class Enclosing {",
-        "  private static final class PrivateEnclosing {",
-        "    @ProducerModule static final class TestModule {",
-        "    }",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("Modules cannot be enclosed in private types")
-        .inFile(moduleFile)
-        .onLine(7);
-  }
-
-  @Test
-  public void includesNonModule() {
-    JavaFileObject xFile =
-        JavaFileObjects.forSourceLines("test.X", "package test;", "", "public final class X {}");
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.FooModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "",
-            "@ProducerModule(includes = X.class)",
-            "public final class FooModule {",
-            "}");
-    Compilation compilation = daggerCompiler().compile(xFile, moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "X is listed as a module, but is not annotated with one of @Module, @ProducerModule");
-  }
-
-  // TODO(ronshapiro): merge this with the equivalent test in ModuleFactoryGeneratorTest and make it
-  // parameterized
-  @Test
-  public void publicModuleNonPublicIncludes() {
-    JavaFileObject publicModuleFile = JavaFileObjects.forSourceLines("test.PublicModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "",
-        "@ProducerModule(includes = {",
-        "    BadNonPublicModule.class, OtherPublicModule.class, OkNonPublicModule.class",
-        "})",
-        "public final class PublicModule {",
-        "}");
-    JavaFileObject badNonPublicModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.BadNonPublicModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "final class BadNonPublicModule {",
-            "  @Produces",
-            "  int produceInt() {",
-            "    return 42;",
-            "  }",
-            "}");
-    JavaFileObject okNonPublicModuleFile = JavaFileObjects.forSourceLines("test.OkNonPublicModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "",
-        "@ProducerModule",
-        "final class OkNonPublicModule {",
-        "  @Produces",
-        "  static String produceString() {",
-        "    return \"foo\";",
-        "  }",
-        "}");
-    JavaFileObject otherPublicModuleFile = JavaFileObjects.forSourceLines("test.OtherPublicModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "",
-        "@ProducerModule",
-        "public final class OtherPublicModule {",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                publicModuleFile,
-                badNonPublicModuleFile,
-                okNonPublicModuleFile,
-                otherPublicModuleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "This module is public, but it includes non-public (or effectively non-public) modules "
-                + "(test.BadNonPublicModule) that have non-static, non-abstract binding methods. "
-                + "Either reduce the visibility of this module, make the included modules public, "
-                + "or make all of the binding methods on the included modules abstract or static.")
-        .inFile(publicModuleFile)
-        .onLine(8);
-  }
-
-  @Test public void argumentNamedModuleCompiles() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "",
-        "@ProducerModule",
-        "final class TestModule {",
-        "  @Produces String produceString(int module) {",
-        "    return null;",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(moduleFile);
-    assertThat(compilation).succeeded();
-  }
-
-  @Test public void singleProducesMethodNoArgsFuture() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "",
-        "@ProducerModule",
-        "final class TestModule {",
-        "  @Produces ListenableFuture<String> produceString() {",
-        "    return null;",
-        "  }",
-        "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProduceStringFactory",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.Futures;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.internal.AbstractProducesMethodProducer;",
-            "import dagger.producers.monitoring.ProducerToken;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            "@SuppressWarnings(\"FutureReturnValueIgnored\")",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProduceStringFactory",
-            "    extends AbstractProducesMethodProducer<Void, String> {",
-            "  private final TestModule module;",
-            "",
-            "  private TestModule_ProduceStringFactory(",
-            "      TestModule module,",
-            "      Provider<Executor> executorProvider,",
-            "      Provider<ProductionComponentMonitor> productionComponentMonitorProvider) {",
-            "    super(",
-            "        productionComponentMonitorProvider,",
-            "        ProducerToken.create(TestModule_ProduceStringFactory.class),",
-            "        executorProvider);",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  public static TestModule_ProduceStringFactory create(",
-            "      TestModule module,",
-            "      Provider<Executor> executorProvider,",
-            "      Provider<ProductionComponentMonitor> productionComponentMonitorProvider) {",
-            "    return new TestModule_ProduceStringFactory(",
-            "        module, executorProvider, productionComponentMonitorProvider);",
-            "  }",
-            "",
-            "  @Override protected ListenableFuture<Void> collectDependencies() {",
-            "    return Futures.<Void>immediateFuture(null);",
-            "  }",
-            "",
-            "  @Override public ListenableFuture<String> callProducesMethod(Void ignoredVoidArg) {",
-            "    return module.produceString();",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(moduleFile)
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(factoryFile);
-  }
-
-  @Test
-  public void singleProducesMethodNoArgsFutureWithProducerName() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.Futures;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "",
-            "@ProducerModule",
-            "final class TestModule {",
-            "  @Produces ListenableFuture<String> produceString() {",
-            "    return Futures.immediateFuture(\"\");",
-            "  }",
-            "}");
-    JavaFileObject factoryFile =
-        JavaFileObjects.forSourceLines(
-            "TestModule_ProduceStringFactory",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.Futures;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.internal.AbstractProducesMethodProducer;",
-            "import dagger.producers.monitoring.ProducerToken;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "import java.util.concurrent.Executor;",
-            IMPORT_GENERATED_ANNOTATION,
-            "import javax.inject.Provider;",
-            "",
-            "@SuppressWarnings(\"FutureReturnValueIgnored\")",
-            GENERATED_ANNOTATION,
-            "public final class TestModule_ProduceStringFactory",
-            "    extends AbstractProducesMethodProducer<Void, String> {",
-            "  private final TestModule module;",
-            "",
-            "  private TestModule_ProduceStringFactory(",
-            "      TestModule module,",
-            "      Provider<Executor> executorProvider,",
-            "      Provider<ProductionComponentMonitor> productionComponentMonitorProvider) {",
-            "    super(",
-            "        productionComponentMonitorProvider,",
-            "        ProducerToken.create(\"test.TestModule#produceString\"),",
-            "        executorProvider);",
-            "    this.module = module;",
-            "  }",
-            "",
-            "  public static TestModule_ProduceStringFactory create(",
-            "      TestModule module,",
-            "      Provider<Executor> executorProvider,",
-            "      Provider<ProductionComponentMonitor> productionComponentMonitorProvider) {",
-            "    return new TestModule_ProduceStringFactory(",
-            "        module, executorProvider, productionComponentMonitorProvider);",
-            "  }",
-            "",
-            "  @Override protected ListenableFuture<Void> collectDependencies() {",
-            "    return Futures.<Void>immediateFuture(null);",
-            "  }",
-            "",
-            "  @Override public ListenableFuture<String> callProducesMethod(Void ignoredVoidArg) {",
-            "    return module.produceString();",
-            "  }",
-            "}");
-    assertAbout(javaSource())
-        .that(moduleFile)
-        .withCompilerOptions("-Adagger.writeProducerNameInToken=ENABLED")
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(factoryFile);
-  }
-
-  @Test
-  public void producesMethodMultipleQualifiersOnMethod() {
-    assertThatProductionModuleMethod(
-            "@Produces @QualifierA @QualifierB static String produceString() { return null; }")
-        .importing(ListenableFuture.class, QualifierA.class, QualifierB.class)
-        .hasError("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void producesMethodMultipleQualifiersOnParameter() {
-    assertThatProductionModuleMethod(
-            "@Produces static String produceString(@QualifierA @QualifierB Object input) "
-                + "{ return null; }")
-        .importing(ListenableFuture.class, QualifierA.class, QualifierB.class)
-        .hasError("may not use more than one @Qualifier");
-  }
-
-  @Test
-  public void producesMethodWildcardDependency() {
-    assertThatProductionModuleMethod(
-            "@Produces static String produceString(Provider<? extends Number> numberProvider) "
-                + "{ return null; }")
-        .importing(ListenableFuture.class, QualifierA.class, QualifierB.class)
-        .hasError(
-            "Dagger does not support injecting Provider<T>, Lazy<T>, Producer<T>, or Produced<T> "
-                + "when T is a wildcard type such as ? extends java.lang.Number");
-  }
-
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface QualifierA {}
-
-  @Qualifier
-  @Retention(RUNTIME)
-  public @interface QualifierB {}
-}
diff --git a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java b/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java
deleted file mode 100644
index 9a852c7..0000000
--- a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java
+++ /dev/null
@@ -1,671 +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.truth.Truth.assertAbout;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ProductionComponentProcessorTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public ProductionComponentProcessorTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test public void componentOnConcreteClass() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "@ProductionComponent",
-        "final class NotAComponent {}");
-    Compilation compilation = daggerCompiler().compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void componentOnEnum() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "@ProductionComponent",
-        "enum NotAComponent {",
-        "  INSTANCE",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void componentOnAnnotation() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "@ProductionComponent",
-        "@interface NotAComponent {}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void nonModuleModule() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.NotAComponent",
-        "package test;",
-        "",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "@ProductionComponent(modules = Object.class)",
-        "interface NotAComponent {}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("is not annotated with one of @Module, @ProducerModule");
-  }
-
-  @Test
-  public void dependsOnProductionExecutor() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.ExecutorModule",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.MoreExecutors;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.producers.Production;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@Module",
-            "final class ExecutorModule {",
-            "  @Provides @Production Executor executor() {",
-            "    return MoreExecutors.directExecutor();",
-            "  }",
-            "}");
-    JavaFileObject producerModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.Production;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@ProducerModule",
-            "final class SimpleModule {",
-            "  @Produces String str(@Production Executor executor) {",
-            "    return \"\";",
-            "  }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleComponent",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionComponent;",
-            "import java.util.concurrent.Executor;",
-            "",
-            "@ProductionComponent(modules = {ExecutorModule.class, SimpleModule.class})",
-            "interface SimpleComponent {",
-            "  ListenableFuture<String> str();",
-            "",
-            "  @ProductionComponent.Builder",
-            "  interface Builder {",
-            "    SimpleComponent build();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .compile(moduleFile, producerModuleFile, componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("java.lang.String may not depend on the production executor")
-        .inFile(componentFile)
-        .onLineContaining("interface SimpleComponent");
-
-    compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(producerModuleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("java.lang.String may not depend on the production executor")
-        .inFile(producerModuleFile)
-        .onLineContaining("class SimpleModule");
-    // TODO(dpb): Report at the binding if enclosed in the module.
-  }
-
-  @Test
-  public void simpleComponent() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import com.google.common.util.concurrent.MoreExecutors;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.Production;",
-            "import dagger.producers.ProductionComponent;",
-            "import java.util.concurrent.Executor;",
-            "import javax.inject.Inject;",
-            "",
-            "final class TestClass {",
-            "  static final class C {",
-            "    @Inject C() {}",
-            "  }",
-            "",
-            "  interface A {}",
-            "  interface B {}",
-            "",
-            "  @Module",
-            "  static final class BModule {",
-            "    @Provides B b(C c) {",
-            "      return null;",
-            "    }",
-            "",
-            "    @Provides @Production Executor executor() {",
-            "      return MoreExecutors.directExecutor();",
-            "    }",
-            "  }",
-            "",
-            "  @ProducerModule",
-            "  static final class AModule {",
-            "    @Produces ListenableFuture<A> a(B b) {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(modules = {AModule.class, BModule.class})",
-            "  interface SimpleComponent {",
-            "    ListenableFuture<A> a();",
-            "  }",
-            "}");
-    JavaFileObject generatedComponent;
-    switch (compilerMode) {
-      case FAST_INIT_MODE:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestClass_SimpleComponent",
-                "package test;",
-                "",
-                "import com.google.common.util.concurrent.ListenableFuture;",
-                "import dagger.internal.DoubleCheck;",
-                "import dagger.internal.InstanceFactory;",
-                "import dagger.internal.MemoizedSentinel;",
-                "import dagger.internal.Preconditions;",
-                "import dagger.internal.SetFactory;",
-                "import dagger.producers.Producer;",
-                "import dagger.producers.internal.CancellationListener;",
-                "import dagger.producers.internal.Producers;",
-                "import dagger.producers.monitoring.ProductionComponentMonitor;",
-                "import java.util.concurrent.Executor;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestClass_SimpleComponent",
-                "    implements TestClass.SimpleComponent, CancellationListener {",
-                "  private final TestClass.BModule bModule;",
-                "  private volatile Object productionImplementationExecutor =",
-                "      new MemoizedSentinel();",
-                "  private volatile Provider<Executor> productionImplementationExecutorProvider;",
-                "  private volatile Object productionComponentMonitor = new MemoizedSentinel();",
-                "  private volatile Provider<ProductionComponentMonitor> monitorProvider;",
-                "  private volatile Provider<TestClass.B> bProvider;",
-                "  private Producer<TestClass.A> aEntryPoint;",
-                "  private Provider<TestClass.SimpleComponent> simpleComponentProvider;",
-                "  private Producer<TestClass.B> bProducer;",
-                "  private Producer<TestClass.A> aProducer;",
-                "",
-                "  private DaggerTestClass_SimpleComponent(",
-                "      TestClass.AModule aModuleParam,",
-                "      TestClass.BModule bModuleParam) {",
-                "    this.bModule = bModuleParam;",
-                "    initialize(aModuleParam, bModuleParam);",
-                "  }",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static TestClass.SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  private Executor getProductionImplementationExecutor() {",
-                "    Object local = productionImplementationExecutor;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = productionImplementationExecutor;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local =",
-                "              TestClass_BModule_ExecutorFactory.executor(bModule);",
-                "          productionImplementationExecutor =",
-                "              DoubleCheck.reentrantCheck(",
-                "                  productionImplementationExecutor, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (Executor) local;",
-                "  }",
-                "",
-                "  private Provider<Executor> getProductionImplementationExecutorProvider() {",
-                "    Object local = productionImplementationExecutorProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      productionImplementationExecutorProvider = (Provider<Executor>) local;",
-                "    }",
-                "    return (Provider<Executor>) local;",
-                "  }",
-                "",
-                "  private ProductionComponentMonitor getProductionComponentMonitor() {",
-                "    Object local = productionComponentMonitor;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = productionComponentMonitor;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local =",
-                "              TestClass_SimpleComponent_MonitoringModule_MonitorFactory",
-                "                  .monitor(",
-                "                      simpleComponentProvider,",
-                "                      SetFactory.<ProductionComponentMonitor.Factory>empty());",
-                "          productionComponentMonitor =",
-                "              DoubleCheck.reentrantCheck(",
-                "                  productionComponentMonitor, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (ProductionComponentMonitor) local;",
-                "  }",
-                "",
-                "  private Provider<ProductionComponentMonitor>",
-                "      getProductionComponentMonitorProvider() {",
-                "      Object local = monitorProvider;",
-                "      if (local == null) {",
-                "        local = new SwitchingProvider<>(1);",
-                "        monitorProvider = (Provider<ProductionComponentMonitor>) local;",
-                "      }",
-                "      return (Provider<ProductionComponentMonitor>) local;",
-                "  }",
-                "",
-                "  private TestClass.B getB() {",
-                "    return TestClass_BModule_BFactory.b(bModule, new TestClass.C());",
-                "  }",
-                "",
-                "  private Provider<TestClass.B> getBProvider() {",
-                "    Object local = bProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(2);",
-                "      bProvider = (Provider<TestClass.B>) local;",
-                "    }",
-                "    return (Provider<TestClass.B>) local;",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "      final TestClass.AModule aModuleParam,",
-                "      final TestClass.BModule bModuleParam) {",
-                "    this.simpleComponentProvider =",
-                "        InstanceFactory.create((TestClass.SimpleComponent) this);",
-                "    this.bProducer = Producers.producerFromProvider(getBProvider());",
-                "    this.aProducer =",
-                "        TestClass_AModule_AFactory.create(",
-                "            aModuleParam,",
-                "            getProductionImplementationExecutorProvider(),",
-                "            getProductionComponentMonitorProvider(),",
-                "            bProducer);",
-                "    this.aEntryPoint = Producers.entryPointViewOf(aProducer, this);",
-                "  }",
-                "",
-                "  @Override",
-                "  public ListenableFuture<TestClass.A> a() {",
-                "    return aEntryPoint.get();",
-                "  }",
-                "",
-                "  @Override",
-                "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-                "    Producers.cancel(aProducer, mayInterruptIfRunning);",
-                "    Producers.cancel(bProducer, mayInterruptIfRunning);",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private TestClass.AModule aModule;",
-                "    private TestClass.BModule bModule;",
-                "",
-                "    private Builder() {}",
-                "",
-                "    public Builder aModule(TestClass.AModule aModule) {",
-                "      this.aModule = Preconditions.checkNotNull(aModule);",
-                "      return this;",
-                "    }",
-                "",
-                "    public Builder bModule(TestClass.BModule bModule) {",
-                "      this.bModule = Preconditions.checkNotNull(bModule);",
-                "      return this;",
-                "    }",
-                "",
-                "    public TestClass.SimpleComponent build() {",
-                "      if (aModule == null) {",
-                "        this.aModule = new TestClass.AModule();",
-                "      }",
-                "      if (bModule == null) {",
-                "        this.bModule = new TestClass.BModule();",
-                "      }",
-                "      return new DaggerTestClass_SimpleComponent(aModule, bModule);",
-                "    }",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    private final int id;",
-                "",
-                "    SwitchingProvider(int id) {",
-                "      this.id = id;",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: return (T) DaggerTestClass_SimpleComponent.this",
-                "            .getProductionImplementationExecutor();",
-                "        case 1: return (T)",
-                "            DaggerTestClass_SimpleComponent.this.getProductionComponentMonitor();",
-                "        case 2: return (T)",
-                "            DaggerTestClass_SimpleComponent.this.getB();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-        break;
-      default:
-        generatedComponent =
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestClass_SimpleComponent",
-                "package test;",
-                "",
-                "import com.google.common.util.concurrent.ListenableFuture;",
-                "import dagger.internal.DoubleCheck;",
-                "import dagger.internal.InstanceFactory;",
-                "import dagger.internal.Preconditions;",
-                "import dagger.internal.SetFactory;",
-                "import dagger.producers.Producer;",
-                "import dagger.producers.internal.CancellationListener;",
-                "import dagger.producers.internal.Producers;",
-                "import dagger.producers.monitoring.ProductionComponentMonitor;",
-                "import java.util.concurrent.Executor;",
-                IMPORT_GENERATED_ANNOTATION,
-                "import javax.inject.Provider;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestClass_SimpleComponent",
-                "    implements TestClass.SimpleComponent, CancellationListener {",
-                "  private Producer<TestClass.A> aEntryPoint;",
-                "  private Provider<Executor> executorProvider;",
-                "  private Provider<Executor> productionImplementationExecutorProvider;",
-                "  private Provider<TestClass.SimpleComponent> simpleComponentProvider;",
-                "  private Provider<ProductionComponentMonitor> monitorProvider;",
-                "  private Provider<TestClass.B> bProvider;",
-                "  private Producer<TestClass.B> bProducer;",
-                "  private Producer<TestClass.A> aProducer;",
-                "",
-                "  private DaggerTestClass_SimpleComponent(",
-                "      TestClass.AModule aModuleParam,",
-                "      TestClass.BModule bModuleParam) {",
-                "    initialize(aModuleParam, bModuleParam);",
-                "  }",
-                "",
-                "  public static Builder builder() {",
-                "    return new Builder();",
-                "  }",
-                "",
-                "  public static TestClass.SimpleComponent create() {",
-                "    return new Builder().build();",
-                "  }",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize(",
-                "      final TestClass.AModule aModuleParam,",
-                "      final TestClass.BModule bModuleParam) {",
-                "    this.executorProvider =",
-                "        TestClass_BModule_ExecutorFactory.create(bModuleParam);",
-                "    this.productionImplementationExecutorProvider =",
-                "        DoubleCheck.provider((Provider) executorProvider);",
-                "    this.simpleComponentProvider = ",
-                "        InstanceFactory.create((TestClass.SimpleComponent) this);",
-                "    this.monitorProvider =",
-                "        DoubleCheck.provider(",
-                "            TestClass_SimpleComponent_MonitoringModule_MonitorFactory.create(",
-                "                simpleComponentProvider,",
-                "                SetFactory.<ProductionComponentMonitor.Factory>empty()));",
-                "    this.bProvider = TestClass_BModule_BFactory.create(",
-                "        bModuleParam, TestClass_C_Factory.create());",
-                "    this.bProducer = Producers.producerFromProvider(bProvider);",
-                "    this.aProducer = TestClass_AModule_AFactory.create(",
-                "        aModuleParam,",
-                "        productionImplementationExecutorProvider,",
-                "        monitorProvider,",
-                "        bProducer);",
-                "    this.aEntryPoint = Producers.entryPointViewOf(aProducer, this);",
-                "  }",
-                "",
-                "  @Override",
-                "  public ListenableFuture<TestClass.A> a() {",
-                "    return aEntryPoint.get();",
-                "  }",
-                "",
-                "  @Override",
-                "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {",
-                "    Producers.cancel(aProducer, mayInterruptIfRunning);",
-                "    Producers.cancel(bProducer, mayInterruptIfRunning);",
-                "  }",
-                "",
-                "  static final class Builder {",
-                "    private TestClass.AModule aModule;",
-                "    private TestClass.BModule bModule;",
-                "",
-                "    private Builder() {}",
-                "",
-                "    public Builder aModule(TestClass.AModule aModule) {",
-                "      this.aModule = Preconditions.checkNotNull(aModule);",
-                "      return this;",
-                "    }",
-                "",
-                "    public Builder bModule(TestClass.BModule bModule) {",
-                "      this.bModule = Preconditions.checkNotNull(bModule);",
-                "      return this;",
-                "    }",
-                "",
-                "    public TestClass.SimpleComponent build() {",
-                "      if (aModule == null) {",
-                "        this.aModule = new TestClass.AModule();",
-                "      }",
-                "      if (bModule == null) {",
-                "        this.bModule = new TestClass.BModule();",
-                "      }",
-                "      return new DaggerTestClass_SimpleComponent(aModule, bModule);",
-                "    }",
-                "  }",
-                "}");
-    }
-    assertAbout(javaSource())
-        .that(component)
-        .withCompilerOptions(compilerMode.javacopts())
-        .processedWith(new ComponentProcessor())
-        .compilesWithoutError()
-        .and()
-        .generatesSources(generatedComponent);
-  }
-
-  @Test public void nullableProducersAreNotErrors() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import com.google.common.util.concurrent.MoreExecutors;",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "import dagger.producers.Production;",
-        "import dagger.producers.ProductionComponent;",
-        "import java.util.concurrent.Executor;",
-        "import javax.annotation.Nullable;",
-        "import javax.inject.Inject;",
-        "",
-        "final class TestClass {",
-        "  interface A {}",
-        "  interface B {}",
-        "  interface C {}",
-        "",
-        "  @Module",
-        "  static final class CModule {",
-        "    @Provides @Nullable C c() {",
-        "      return null;",
-        "    }",
-        "",
-        "    @Provides @Production Executor executor() {",
-        "      return MoreExecutors.directExecutor();",
-        "    }",
-        "  }",
-        "",
-        "  @ProducerModule",
-        "  static final class ABModule {",
-        "    @Produces @Nullable B b(@Nullable C c) {",
-        "      return null;",
-        "    }",
-
-        "    @Produces @Nullable ListenableFuture<A> a(B b) {",  // NOTE: B not injected as nullable
-        "      return null;",
-        "    }",
-        "  }",
-        "",
-        "  @ProductionComponent(modules = {ABModule.class, CModule.class})",
-        "  interface SimpleComponent {",
-        "    ListenableFuture<A> a();",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining("@Nullable on @Produces methods does not do anything")
-        .inFile(component)
-        .onLine(33);
-    assertThat(compilation)
-        .hadWarningContaining("@Nullable on @Produces methods does not do anything")
-        .inFile(component)
-        .onLine(36);
-  }
-
-  @Test
-  public void productionScope_injectConstructor() {
-    JavaFileObject productionScoped =
-        JavaFileObjects.forSourceLines(
-            "test.ProductionScoped",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionScope;",
-            "import javax.inject.Inject;",
-            "",
-            "@ProductionScope",
-            "class ProductionScoped {",
-            "  @Inject ProductionScoped() {}",
-            "}");
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.producers.ProductionSubcomponent;",
-            "",
-            "@ProductionSubcomponent",
-            "interface Child {",
-            "  ProductionScoped productionScoped();",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(productionScoped, parent, child);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(
-            new JavaFileBuilder(compilerMode, "test.DaggerRoot")
-                .addLines(
-                    "package test;",
-                    GENERATED_ANNOTATION,
-                    "final class DaggerParent implements Parent, CancellationListener {",
-                    "  private final class ChildImpl implements Child, CancellationListener {",
-                    "    @Override",
-                    "    public ProductionScoped productionScoped() {")
-                .addLinesIn(
-                    CompilerMode.DEFAULT_MODE, //
-                    "      return DaggerParent.this.productionScopedProvider.get();")
-                .addLinesIn(
-                    CompilerMode.FAST_INIT_MODE, //
-                    "      return DaggerParent.this.getProductionScoped();")
-                .addLines(
-                    "    }", //
-                    "  }", //
-                    "}")
-                .build());
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java b/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java
deleted file mode 100644
index 8453e03..0000000
--- a/javatests/dagger/internal/codegen/ProductionGraphValidationTest.java
+++ /dev/null
@@ -1,495 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Producer-specific validation tests. */
-@RunWith(JUnit4.class)
-public class ProductionGraphValidationTest {
-  private static final JavaFileObject EXECUTOR_MODULE =
-      JavaFileObjects.forSourceLines(
-          "test.ExecutorModule",
-          "package test;",
-          "",
-          "import com.google.common.util.concurrent.MoreExecutors;",
-          "import dagger.Module;",
-          "import dagger.Provides;",
-          "import dagger.producers.Production;",
-          "import java.util.concurrent.Executor;",
-          "",
-          "@Module",
-          "class ExecutorModule {",
-          "  @Provides @Production Executor executor() {",
-          "    return MoreExecutors.directExecutor();",
-          "  }",
-          "}");
-
-  @Test public void componentWithUnprovidedInput() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.MyComponent",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "@ProductionComponent(modules = {ExecutorModule.class, FooModule.class})",
-        "interface MyComponent {",
-        "  ListenableFuture<Foo> getFoo();",
-        "}");
-    JavaFileObject module = JavaFileObjects.forSourceLines("test.FooModule",
-        "package test;",
-        "",
-        "import dagger.producers.ProducerModule;",
-        "import dagger.producers.Produces;",
-        "",
-        "class Foo {}",
-        "class Bar {}",
-        "",
-        "@ProducerModule",
-        "class FooModule {",
-        "  @Produces Foo foo(Bar bar) {",
-        "    return null;",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, module, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.Bar cannot be provided without an @Inject constructor or an @Provides- or "
-                + "@Produces-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface MyComponent");
-  }
-
-  @Test public void componentProductionWithNoDependencyChain() {
-    JavaFileObject component = JavaFileObjects.forSourceLines("test.TestClass",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import dagger.producers.ProductionComponent;",
-        "",
-        "final class TestClass {",
-        "  interface A {}",
-        "",
-        "  @ProductionComponent(modules = ExecutorModule.class)",
-        "  interface AComponent {",
-        "    ListenableFuture<A> getA();",
-        "  }",
-        "}");
-
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestClass.A cannot be provided without an @Provides- or @Produces-annotated "
-                + "method.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test public void provisionDependsOnProduction() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.Provides;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "  interface B {}",
-            "",
-            "  @ProducerModule(includes = BModule.class)",
-            "  final class AModule {",
-            "    @Provides A a(B b) {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProducerModule",
-            "  final class BModule {",
-            "    @Produces ListenableFuture<B> b() {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(modules = {ExecutorModule.class, AModule.class})",
-            "  interface AComponent {",
-            "    ListenableFuture<A> getA();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.TestClass.A is a provision, which cannot depend on a production.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-
-    compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.TestClass.A is a provision, which cannot depend on a production.")
-        .inFile(component)
-        .onLineContaining("class AModule");
-  }
-
-  @Test public void provisionEntryPointDependsOnProduction() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "",
-            "  @ProducerModule",
-            "  static final class AModule {",
-            "    @Produces ListenableFuture<A> a() {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(modules = {ExecutorModule.class, AModule.class})",
-            "  interface AComponent {",
-            "    A getA();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestClass.A is a provision entry-point, which cannot depend on a production.")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test
-  public void providingMultibindingWithProductions() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.ProductionComponent;",
-            "import java.util.Map;",
-            "import javax.inject.Provider;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "  interface B {}",
-            "",
-            "  @Module",
-            "  static final class AModule {",
-            "    @Provides static A a(Map<String, Provider<Object>> map) {",
-            "      return null;",
-            "    }",
-            "",
-            "    @Provides @IntoMap @StringKey(\"a\") static Object aEntry() {",
-            "      return \"a\";",
-            "    }",
-            "  }",
-            "",
-            "  @ProducerModule",
-            "  static final class BModule {",
-            "    @Produces static B b(A a) {",
-            "      return null;",
-            "    }",
-            "",
-            "    @Produces @IntoMap @StringKey(\"b\") static Object bEntry() {",
-            "      return \"b\";",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(",
-            "      modules = {ExecutorModule.class, AModule.class, BModule.class})",
-            "  interface AComponent {",
-            "    ListenableFuture<B> b();",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.TestClass.A is a provision, which cannot depend on a production")
-        .inFile(component)
-        .onLineContaining("interface AComponent");
-  }
-
-  @Test
-  public void monitoringDependsOnUnboundType() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.ProductionComponent;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "",
-            "  @Module",
-            "  final class MonitoringModule {",
-            "    @Provides @IntoSet",
-            "    ProductionComponentMonitor.Factory monitorFactory(A unbound) {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProducerModule",
-            "  final class StringModule {",
-            "    @Produces ListenableFuture<String> str() {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(",
-            "    modules = {ExecutorModule.class, MonitoringModule.class, StringModule.class}",
-            "  )",
-            "  interface StringComponent {",
-            "    ListenableFuture<String> getString();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestClass.A cannot be provided without an @Provides-annotated method.")
-        .inFile(component)
-        .onLineContaining("interface StringComponent");
-  }
-
-  @Test
-  public void monitoringDependsOnProduction() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestClass",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.producers.ProductionComponent;",
-            "import dagger.producers.monitoring.ProductionComponentMonitor;",
-            "",
-            "final class TestClass {",
-            "  interface A {}",
-            "",
-            "  @Module",
-            "  final class MonitoringModule {",
-            "    @Provides @IntoSet ProductionComponentMonitor.Factory monitorFactory(A a) {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProducerModule",
-            "  final class StringModule {",
-            "    @Produces A a() {",
-            "      return null;",
-            "    }",
-            "",
-            "    @Produces ListenableFuture<String> str() {",
-            "      return null;",
-            "    }",
-            "  }",
-            "",
-            "  @ProductionComponent(",
-            "    modules = {ExecutorModule.class, MonitoringModule.class, StringModule.class}",
-            "  )",
-            "  interface StringComponent {",
-            "    ListenableFuture<String> getString();",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.util.Set<dagger.producers.monitoring.ProductionComponentMonitor.Factory>"
-                + " test.TestClass.MonitoringModule#monitorFactory is a provision,"
-                + " which cannot depend on a production.")
-        .inFile(component)
-        .onLineContaining("interface StringComponent");
-  }
-
-  @Test
-  public void cycleNotBrokenByMap() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})",
-            "interface TestComponent {",
-            "  ListenableFuture<String> string();",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.multibindings.IntoMap;",
-            "import dagger.multibindings.StringKey;",
-            "import java.util.Map;",
-            "",
-            "@ProducerModule",
-            "final class TestModule {",
-            "  @Produces static String string(Map<String, String> map) {",
-            "    return \"string\";",
-            "  }",
-            "",
-            "  @Produces @IntoMap @StringKey(\"key\")",
-            "  static String entry(String string) {",
-            "    return string;",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component, module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cycle")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void cycleNotBrokenByProducerMap() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.ProductionComponent;",
-            "",
-            "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})",
-            "interface TestComponent {",
-            "  ListenableFuture<String> string();",
-            "}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.producers.Producer;",
-            "import dagger.producers.ProducerModule;",
-            "import dagger.producers.Produces;",
-            "import dagger.multibindings.StringKey;",
-            "import dagger.multibindings.IntoMap;",
-            "import java.util.Map;",
-            "",
-            "@ProducerModule",
-            "final class TestModule {",
-            "  @Produces static String string(Map<String, Producer<String>> map) {",
-            "    return \"string\";",
-            "  }",
-            "",
-            "  @Produces @IntoMap @StringKey(\"key\")",
-            "  static String entry(String string) {",
-            "    return string;",
-            "  }",
-            "}");
-    Compilation compilation = daggerCompiler().compile(EXECUTOR_MODULE, component, module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("cycle")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-  
-  @Test
-  public void componentWithBadModule() {
-    JavaFileObject badModule =
-        JavaFileObjects.forSourceLines(
-            "test.BadModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.multibindings.Multibinds;",
-            "import dagger.Module;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "abstract class BadModule {",
-            "  @Multibinds",
-            "  @BindsOptionalOf",
-            "  abstract Set<String> strings();",
-            "}");
-    JavaFileObject badComponent =
-        JavaFileObjects.forSourceLines(
-            "test.BadComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Optional;",
-            "import java.util.Set;",
-            "",
-            "@Component(modules = BadModule.class)",
-            "interface BadComponent {",
-            "  Set<String> strings();",
-            "  Optional<Set<String>> optionalStrings();",
-            "}");
-    Compilation compilation = daggerCompiler().compile(badModule, badComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("test.BadModule has errors")
-        .inFile(badComponent)
-        .onLine(7);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/RepeatedModuleValidationTest.java b/javatests/dagger/internal/codegen/RepeatedModuleValidationTest.java
deleted file mode 100644
index 60a9bd5..0000000
--- a/javatests/dagger/internal/codegen/RepeatedModuleValidationTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class RepeatedModuleValidationTest {
-  private static final JavaFileObject MODULE_FILE =
-      JavaFileObjects.forSourceLines(
-          "test.TestModule",
-          "package test;",
-          "",
-          "import dagger.Module;",
-          "",
-          "@Module",
-          "final class TestModule {}");
-
-  @Test
-  public void moduleRepeatedInSubcomponentFactoryMethod() {
-    JavaFileObject subcomponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = TestModule.class)",
-            "interface TestSubcomponent {",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  TestSubcomponent newTestSubcomponent(TestModule module);",
-            "}");
-    Compilation compilation =
-        daggerCompiler().compile(MODULE_FILE, subcomponentFile, componentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("TestModule is present in test.TestComponent.")
-        .inFile(componentFile)
-        .onLine(7)
-        .atColumn(51);
-  }
-
-  @Test
-  public void moduleRepeatedInSubcomponentBuilderMethod() {
-    JavaFileObject subcomponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = TestModule.class)",
-            "interface TestSubcomponent {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Builder testModule(TestModule testModule);",
-            "    TestSubcomponent build();",
-            "  }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  TestSubcomponent.Builder newTestSubcomponentBuilder();",
-            "}");
-    Compilation compilation =
-        daggerCompiler().compile(MODULE_FILE, subcomponentFile, componentFile);
-    assertThat(compilation).succeeded();
-    // TODO(gak): assert about the warning when we have that ability
-  }
-
-  @Test
-  public void moduleRepeatedButNotPassed() {
-    JavaFileObject subcomponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = TestModule.class)",
-            "interface TestSubcomponent {",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  TestSubcomponent newTestSubcomponent();",
-            "}");
-    Compilation compilation =
-        daggerCompiler().compile(MODULE_FILE, subcomponentFile, componentFile);
-    assertThat(compilation).succeeded();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ScopingValidationTest.java b/javatests/dagger/internal/codegen/ScopingValidationTest.java
deleted file mode 100644
index 9efcc2a..0000000
--- a/javatests/dagger/internal/codegen/ScopingValidationTest.java
+++ /dev/null
@@ -1,700 +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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ScopingValidationTest {
-  @Test
-  public void componentWithoutScopeIncludesScopedBindings_Fail() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.MyComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Component(modules = ScopedModule.class)",
-            "interface MyComponent {",
-            "  ScopedType string();",
-            "}");
-    JavaFileObject typeFile =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "class ScopedType {",
-            "  @Inject ScopedType(String s, long l, float f) {}",
-            "}");
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "class ScopedModule {",
-            "  @Provides @Singleton String string() { return \"a string\"; }",
-            "  @Provides long integer() { return 0L; }",
-            "  @Provides float floatingPoint() { return 0.0f; }",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(componentFile, typeFile, moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.MyComponent (unscoped) may not reference scoped bindings:",
-                "    @Singleton class test.ScopedType",
-                "    @Provides @Singleton String test.ScopedModule.string()"));
-  }
-
-  @Test // b/79859714
-  public void bindsWithChildScope_inParentModule_notAllowed() {
-    JavaFileObject childScope =
-        JavaFileObjects.forSourceLines(
-            "test.ChildScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface ChildScope {}");
-
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "", //
-            "interface Foo {}");
-
-    JavaFileObject fooImpl =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class FooImpl implements Foo {",
-            "  @Inject FooImpl() {}",
-            "}");
-
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "",
-            "@Module",
-            "interface ParentModule {",
-            "  @Binds @ChildScope Foo bind(FooImpl fooImpl);",
-            "}");
-
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@ChildScope",
-            "@Subcomponent",
-            "interface Child {",
-            "  Foo foo();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(childScope, foo, fooImpl, parentModule, parent, child);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.Parent scoped with @Singleton may not reference bindings with different "
-                    + "scopes:",
-                "    @Binds @test.ChildScope test.Foo test.ParentModule.bind(test.FooImpl)"));
-  }
-
-  @Test
-  public void componentWithScopeIncludesIncompatiblyScopedBindings_Fail() {
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.MyComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = ScopedModule.class)",
-            "interface MyComponent {",
-            "  ScopedType string();",
-            "}");
-    JavaFileObject scopeFile =
-        JavaFileObjects.forSourceLines(
-            "test.PerTest",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface PerTest {}");
-    JavaFileObject scopeWithAttribute =
-        JavaFileObjects.forSourceLines(
-            "test.Per",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope",
-            "@interface Per {",
-            "  Class<?> value();",
-            "}");
-    JavaFileObject typeFile =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "@PerTest", // incompatible scope
-            "class ScopedType {",
-            "  @Inject ScopedType(String s, long l, float f, boolean b) {}",
-            "}");
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "class ScopedModule {",
-            "  @Provides @PerTest String string() { return \"a string\"; }", // incompatible scope
-            "  @Provides long integer() { return 0L; }", // unscoped - valid
-            "  @Provides @Singleton float floatingPoint() { return 0.0f; }", // same scope - valid
-            "  @Provides @Per(MyComponent.class) boolean bool() { return false; }", // incompatible
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .compile(componentFile, scopeFile, scopeWithAttribute, typeFile, moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.MyComponent scoped with @Singleton "
-                    + "may not reference bindings with different scopes:",
-                "    @test.PerTest class test.ScopedType",
-                "    @Provides @test.PerTest String test.ScopedModule.string()",
-                "    @Provides @test.Per(test.MyComponent.class) boolean "
-                    + "test.ScopedModule.bool()"))
-        .inFile(componentFile)
-        .onLineContaining("interface MyComponent");
-
-    compilation =
-        daggerCompiler()
-            .withOptions("-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(componentFile, scopeFile, scopeWithAttribute, typeFile, moduleFile);
-    // The @Inject binding for ScopedType should not appear here, but the @Singleton binding should.
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ScopedModule contains bindings with different scopes:",
-                "    @Provides @test.PerTest String test.ScopedModule.string()",
-                "    @Provides @Singleton float test.ScopedModule.floatingPoint()",
-                "    @Provides @test.Per(test.MyComponent.class) boolean "
-                    + "test.ScopedModule.bool()"))
-        .inFile(moduleFile)
-        .onLineContaining("class ScopedModule");
-  }
-
-  @Test
-  public void fullBindingGraphValidationDoesNotReportForOneScope() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                "-Adagger.fullBindingGraphValidation=ERROR",
-                "-Adagger.moduleHasDifferentScopesValidation=ERROR")
-            .compile(
-                JavaFileObjects.forSourceLines(
-                    "test.TestModule",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "import javax.inject.Singleton;",
-                    "",
-                    "@Module",
-                    "interface TestModule {",
-                    "  @Provides @Singleton static Object object() { return \"object\"; }",
-                    "  @Provides @Singleton static String string() { return \"string\"; }",
-                    "  @Provides static int integer() { return 4; }",
-                    "}"));
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void fullBindingGraphValidationDoesNotReportInjectBindings() {
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(
-                "-Adagger.fullBindingGraphValidation=ERROR",
-                "-Adagger.moduleHasDifferentScopesValidation=ERROR")
-            .compile(
-                JavaFileObjects.forSourceLines(
-                    "test.UsedInRootRedScoped",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "@RedScope",
-                    "final class UsedInRootRedScoped {",
-                    "  @Inject UsedInRootRedScoped() {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.UsedInRootBlueScoped",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "@BlueScope",
-                    "final class UsedInRootBlueScoped {",
-                    "  @Inject UsedInRootBlueScoped() {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.RedScope",
-                    "package test;",
-                    "",
-                    "import javax.inject.Scope;",
-                    "",
-                    "@Scope",
-                    "@interface RedScope {}"),
-                JavaFileObjects.forSourceLines(
-                    "test.BlueScope",
-                    "package test;",
-                    "",
-                    "import javax.inject.Scope;",
-                    "",
-                    "@Scope",
-                    "@interface BlueScope {}"),
-                JavaFileObjects.forSourceLines(
-                    "test.TestModule",
-                    "package test;",
-                    "",
-                    "import dagger.Module;",
-                    "import dagger.Provides;",
-                    "import javax.inject.Singleton;",
-                    "",
-                    "@Module(subcomponents = Child.class)",
-                    "interface TestModule {",
-                    "  @Provides @Singleton",
-                    "  static Object object(",
-                    "      UsedInRootRedScoped usedInRootRedScoped,",
-                    "      UsedInRootBlueScoped usedInRootBlueScoped) {",
-                    "    return \"object\";",
-                    "  }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.Child",
-                    "package test;",
-                    "",
-                    "import dagger.Subcomponent;",
-                    "",
-                    "@Subcomponent",
-                    "interface Child {",
-                    "  UsedInChildRedScoped usedInChildRedScoped();",
-                    "  UsedInChildBlueScoped usedInChildBlueScoped();",
-                    "",
-                    "  @Subcomponent.Builder",
-                    "  interface Builder {",
-                    "    Child child();",
-                    "  }",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.UsedInChildRedScoped",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "@RedScope",
-                    "final class UsedInChildRedScoped {",
-                    "  @Inject UsedInChildRedScoped() {}",
-                    "}"),
-                JavaFileObjects.forSourceLines(
-                    "test.UsedInChildBlueScoped",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "@BlueScope",
-                    "final class UsedInChildBlueScoped {",
-                    "  @Inject UsedInChildBlueScoped() {}",
-                    "}"));
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void componentWithScopeMayDependOnOnlyOneScopedComponent() {
-    // If a scoped component will have dependencies, they must only include, at most, a single
-    // scoped component
-    JavaFileObject type =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class SimpleType {",
-            "  @Inject SimpleType() {}",
-            "  static class A { @Inject A() {} }",
-            "  static class B { @Inject B() {} }",
-            "}");
-    JavaFileObject simpleScope =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope @interface SimpleScope {}");
-    JavaFileObject singletonScopedA =
-        JavaFileObjects.forSourceLines(
-            "test.SingletonComponentA",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface SingletonComponentA {",
-            "  SimpleType.A type();",
-            "}");
-    JavaFileObject singletonScopedB =
-        JavaFileObjects.forSourceLines(
-            "test.SingletonComponentB",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface SingletonComponentB {",
-            "  SimpleType.B type();",
-            "}");
-    JavaFileObject scopeless =
-        JavaFileObjects.forSourceLines(
-            "test.ScopelessComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ScopelessComponent {",
-            "  SimpleType type();",
-            "}");
-    JavaFileObject simpleScoped =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleScopedComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@SimpleScope",
-            "@Component(dependencies = {SingletonComponentA.class, SingletonComponentB.class})",
-            "interface SimpleScopedComponent {",
-            "  SimpleType.A type();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .compile(
-                type, simpleScope, simpleScoped, singletonScopedA, singletonScopedB, scopeless);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "@test.SimpleScope test.SimpleScopedComponent depends on more than one scoped "
-                    + "component:",
-                "    @Singleton test.SingletonComponentA",
-                "    @Singleton test.SingletonComponentB"));
-  }
-
-  @Test
-  public void componentWithoutScopeCannotDependOnScopedComponent() {
-    JavaFileObject type =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class SimpleType {",
-            "  @Inject SimpleType() {}",
-            "}");
-    JavaFileObject scopedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.ScopedComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface ScopedComponent {",
-            "  SimpleType type();",
-            "}");
-    JavaFileObject unscopedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.UnscopedComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Component(dependencies = ScopedComponent.class)",
-            "interface UnscopedComponent {",
-            "  SimpleType type();",
-            "}");
-
-    Compilation compilation = daggerCompiler().compile(type, scopedComponent, unscopedComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.UnscopedComponent (unscoped) cannot depend on scoped components:",
-                "    @Singleton test.ScopedComponent"));
-  }
-
-  @Test
-  public void componentWithSingletonScopeMayNotDependOnOtherScope() {
-    // Singleton must be the widest lifetime of present scopes.
-    JavaFileObject type =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class SimpleType {",
-            "  @Inject SimpleType() {}",
-            "}");
-    JavaFileObject simpleScope =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleScope",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope @interface SimpleScope {}");
-    JavaFileObject simpleScoped =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleScopedComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@SimpleScope",
-            "@Component",
-            "interface SimpleScopedComponent {",
-            "  SimpleType type();",
-            "}");
-    JavaFileObject singletonScoped =
-        JavaFileObjects.forSourceLines(
-            "test.SingletonComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(dependencies = SimpleScopedComponent.class)",
-            "interface SingletonComponent {",
-            "  SimpleType type();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(type, simpleScope, simpleScoped, singletonScoped);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "This @Singleton component cannot depend on scoped components:",
-                "    @test.SimpleScope test.SimpleScopedComponent"));
-  }
-
-  @Test
-  public void componentScopeAncestryMustNotCycle() {
-    // The dependency relationship of components is necessarily from shorter lifetimes to
-    // longer lifetimes.  The scoping annotations must reflect this, and so one cannot declare
-    // scopes on components such that they cycle.
-    JavaFileObject type =
-        JavaFileObjects.forSourceLines(
-            "test.SimpleType",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class SimpleType {",
-            "  @Inject SimpleType() {}",
-            "}");
-    JavaFileObject scopeA =
-        JavaFileObjects.forSourceLines(
-            "test.ScopeA",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope @interface ScopeA {}");
-    JavaFileObject scopeB =
-        JavaFileObjects.forSourceLines(
-            "test.ScopeB",
-            "package test;",
-            "",
-            "import javax.inject.Scope;",
-            "",
-            "@Scope @interface ScopeB {}");
-    JavaFileObject longLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentLong",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@ScopeA",
-            "@Component",
-            "interface ComponentLong {",
-            "  SimpleType type();",
-            "}");
-    JavaFileObject mediumLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentMedium",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@ScopeB",
-            "@Component(dependencies = ComponentLong.class)",
-            "interface ComponentMedium {",
-            "  SimpleType type();",
-            "}");
-    JavaFileObject shortLifetime =
-        JavaFileObjects.forSourceLines(
-            "test.ComponentShort",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@ScopeA",
-            "@Component(dependencies = ComponentMedium.class)",
-            "interface ComponentShort {",
-            "  SimpleType type();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().compile(type, scopeA, scopeB, longLifetime, mediumLifetime, shortLifetime);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "test.ComponentShort depends on scoped components in a non-hierarchical scope "
-                    + "ordering:",
-                "    @test.ScopeA test.ComponentLong",
-                "    @test.ScopeB test.ComponentMedium",
-                "    @test.ScopeA test.ComponentShort"));
-  }
-
-  @Test
-  public void reusableNotAllowedOnComponent() {
-    JavaFileObject someComponent =
-        JavaFileObjects.forSourceLines(
-            "test.SomeComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Reusable;",
-            "",
-            "@Reusable",
-            "@Component",
-            "interface SomeComponent {}");
-    Compilation compilation = daggerCompiler().compile(someComponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Reusable cannot be applied to components or subcomponents")
-        .inFile(someComponent)
-        .onLine(6);
-  }
-
-  @Test
-  public void reusableNotAllowedOnSubcomponent() {
-    JavaFileObject someSubcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.SomeComponent",
-            "package test;",
-            "",
-            "import dagger.Reusable;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Reusable",
-            "@Subcomponent",
-            "interface SomeSubcomponent {}");
-    Compilation compilation = daggerCompiler().compile(someSubcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("@Reusable cannot be applied to components or subcomponents")
-        .inFile(someSubcomponent)
-        .onLine(6);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentTest.java b/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentTest.java
deleted file mode 100644
index 3fb0e9c..0000000
--- a/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentTest.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.CLASS_PATH_WITHOUT_GUAVA_OPTION;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.Compiler;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SetBindingRequestFulfillmentTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public SetBindingRequestFulfillmentTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void setBindings() {
-    JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.ElementsIntoSet;",
-        "import dagger.multibindings.Multibinds;",
-        "import java.util.Collections;",
-        "import java.util.Set;",
-        "",
-        "@Module",
-        "abstract class EmptySetModule {",
-        "  @Multibinds abstract Set<Object> objects();",
-        "",
-        "  @Provides @ElementsIntoSet",
-        "  static Set<String> emptySet() { ",
-        "    return Collections.emptySet();",
-        "  }",
-        "}");
-    JavaFileObject setModuleFile = JavaFileObjects.forSourceLines("test.SetModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoSet;",
-        "",
-        "@Module",
-        "final class SetModule {",
-        "  @Provides @IntoSet static String string() { return \"\"; }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Set;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {EmptySetModule.class, SetModule.class})",
-        "interface TestComponent {",
-        "  Set<String> strings();",
-        "  Set<Object> objects();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import dagger.internal.SetBuilder;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public Set<String> strings() {",
-            "    return SetBuilder.<String>newSetBuilder(2)",
-            "        .addAll(EmptySetModule_EmptySetFactory.emptySet())",
-            "        .add(SetModule_StringFactory.string())",
-            "        .build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Set<Object> objects() {",
-            "    return Collections.<Object>emptySet();",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompilerWithoutGuava().compile(emptySetModuleFile, setModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void inaccessible() {
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible",
-            "package other;",
-            "",
-            "class Inaccessible {}");
-    JavaFileObject inaccessible2 =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible2",
-            "package other;",
-            "",
-            "class Inaccessible2 {}");
-    JavaFileObject usesInaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessible",
-            "package other;",
-            "",
-            "import java.util.Set;",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessible {",
-            "  @Inject UsesInaccessible(Set<Inaccessible> set1, Set<Inaccessible2> set2) {}",
-            "}");
-
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.TestModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Collections;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "public abstract class TestModule {",
-            "  @Multibinds abstract Set<Inaccessible> objects();",
-            "",
-            "  @Provides @ElementsIntoSet",
-            "  static Set<Inaccessible2> emptySet() { ",
-            "    return Collections.emptySet();",
-            "  }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "import other.TestModule;",
-            "import other.UsesInaccessible;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  UsesInaccessible usesInaccessible();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import dagger.internal.SetBuilder;",
-            "import other.TestModule_EmptySetFactory;",
-            "import other.UsesInaccessible;",
-            "import other.UsesInaccessible_Factory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private Set getSetOfInaccessible2() {",
-            "    return SetBuilder.newSetBuilder(1)",
-            "        .addAll(TestModule_EmptySetFactory.emptySet())",
-            "        .build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public UsesInaccessible usesInaccessible() {",
-            "    return UsesInaccessible_Factory.newInstance(",
-            "        (Set) Collections.emptySet(),",
-            "        (Set) getSetOfInaccessible2());",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompilerWithoutGuava()
-            .compile(module, inaccessible, inaccessible2, usesInaccessible, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void subcomponentOmitsInheritedBindings() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.multibindings.StringKey;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides @IntoSet static Object parentObject() {",
-            "    return \"parent object\";",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  Set<Object> objectSet();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            "import dagger.internal.Preconditions;",
-            "import java.util.Collections;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private DaggerParent() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static Parent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Child child() {",
-            "    return new ChildImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    @Deprecated",
-            "    public Builder parentModule(ParentModule parentModule) {",
-            "      Preconditions.checkNotNull(parentModule);",
-            "      return this;",
-            "    }",
-            "",
-            "    public Parent build() {",
-            "      return new DaggerParent();",
-            "    }",
-            "  }",
-            "",
-            "  private final class ChildImpl implements Child {",
-            "    private ChildImpl() {}",
-            "",
-            "    @Override",
-            "    public Set<Object> objectSet() {",
-            "      return Collections.<Object>singleton(",
-            "          ParentModule_ParentObjectFactory.parentObject());",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation = daggerCompilerWithoutGuava().compile(parent, parentModule, child);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-
-  private Compiler daggerCompilerWithoutGuava() {
-    return daggerCompiler()
-        .withOptions(compilerMode.javacopts().append(CLASS_PATH_WITHOUT_GUAVA_OPTION));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentWithGuavaTest.java b/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentWithGuavaTest.java
deleted file mode 100644
index 7a47393..0000000
--- a/javatests/dagger/internal/codegen/SetBindingRequestFulfillmentWithGuavaTest.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2017 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SetBindingRequestFulfillmentWithGuavaTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public SetBindingRequestFulfillmentWithGuavaTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test
-  public void setBindings() {
-    JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.ElementsIntoSet;",
-        "import dagger.multibindings.Multibinds;",
-        "import java.util.Collections;",
-        "import java.util.Set;",
-        "",
-        "@Module",
-        "abstract class EmptySetModule {",
-        "  @Multibinds abstract Set<Object> objects();",
-        "",
-        "  @Provides @ElementsIntoSet",
-        "  static Set<String> emptySet() { ",
-        "    return Collections.emptySet();",
-        "  }",
-        "  @Provides @ElementsIntoSet",
-        "  static Set<Integer> onlyContributionIsElementsIntoSet() { ",
-        "    return Collections.emptySet();",
-        "  }",
-        "}");
-    JavaFileObject setModuleFile = JavaFileObjects.forSourceLines("test.SetModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.IntoSet;",
-        "",
-        "@Module",
-        "final class SetModule {",
-        "  @Provides @IntoSet static String string() { return \"\"; }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import java.util.Set;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component(modules = {EmptySetModule.class, SetModule.class})",
-        "interface TestComponent {",
-        "  Set<String> strings();",
-        "  Set<Object> objects();",
-        "  Set<Integer> onlyContributionIsElementsIntoSet();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  @Override",
-            "  public Set<String> strings() {",
-            "    return ImmutableSet.<String>builderWithExpectedSize(2)",
-            "        .addAll(EmptySetModule_EmptySetFactory.emptySet())",
-            "        .add(SetModule_StringFactory.string())",
-            "        .build();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Set<Object> objects() {",
-            "    return ImmutableSet.<Object>of();",
-            "  }",
-            "",
-            "  @Override",
-            "  public Set<Integer> onlyContributionIsElementsIntoSet() {",
-            "    return ImmutableSet.<Integer>copyOf(",
-            "        EmptySetModule_OnlyContributionIsElementsIntoSetFactory",
-            "            .onlyContributionIsElementsIntoSet());",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(emptySetModuleFile, setModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void inaccessible() {
-    JavaFileObject inaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible",
-            "package other;",
-            "",
-            "class Inaccessible {}");
-    JavaFileObject inaccessible2 =
-        JavaFileObjects.forSourceLines(
-            "other.Inaccessible2",
-            "package other;",
-            "",
-            "class Inaccessible2 {}");
-    JavaFileObject usesInaccessible =
-        JavaFileObjects.forSourceLines(
-            "other.UsesInaccessible",
-            "package other;",
-            "",
-            "import java.util.Set;",
-            "import javax.inject.Inject;",
-            "",
-            "public class UsesInaccessible {",
-            "  @Inject UsesInaccessible(Set<Inaccessible> set1, Set<Inaccessible2> set2) {}",
-            "}");
-
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "other.TestModule",
-            "package other;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.ElementsIntoSet;",
-            "import dagger.multibindings.Multibinds;",
-            "import java.util.Collections;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "public abstract class TestModule {",
-            "  @Multibinds abstract Set<Inaccessible> objects();",
-            "",
-            "  @Provides @ElementsIntoSet",
-            "  static Set<Inaccessible2> emptySet() { ",
-            "    return Collections.emptySet();",
-            "  }",
-            "}");
-    JavaFileObject componentFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "import other.TestModule;",
-            "import other.UsesInaccessible;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  UsesInaccessible usesInaccessible();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import other.TestModule_EmptySetFactory;",
-            "import other.UsesInaccessible;",
-            "import other.UsesInaccessible_Factory;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent {",
-            "  private Set getSetOfInaccessible2() {",
-            "    return ImmutableSet.copyOf(TestModule_EmptySetFactory.emptySet());",
-            "  }",
-            "",
-            "  @Override",
-            "  public UsesInaccessible usesInaccessible() {",
-            "    return UsesInaccessible_Factory.newInstance(",
-            "        (Set) ImmutableSet.of(),",
-            "        (Set) getSetOfInaccessible2());",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, inaccessible, inaccessible2, usesInaccessible, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void subcomponentOmitsInheritedBindings() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = ParentModule.class)",
-            "interface Parent {",
-            "  Child child();",
-            "}");
-    JavaFileObject parentModule =
-        JavaFileObjects.forSourceLines(
-            "test.ParentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import dagger.multibindings.IntoSet;",
-            "import dagger.multibindings.StringKey;",
-            "",
-            "@Module",
-            "class ParentModule {",
-            "  @Provides @IntoSet static Object parentObject() {",
-            "    return \"parent object\";",
-            "  }",
-            "}");
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "import java.util.Set;",
-            "",
-            "@Subcomponent",
-            "interface Child {",
-            "  Set<Object> objectSet();",
-            "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParent",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParent implements Parent {",
-            "  private final class ChildImpl implements Child {",
-            "    @Override",
-            "    public Set<Object> objectSet() {",
-            "      return ImmutableSet.<Object>of(",
-            "          ParentModule_ParentObjectFactory.parentObject());",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent, parentModule, child);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void productionComponents() {
-    JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import dagger.multibindings.ElementsIntoSet;",
-        "import java.util.Collections;",
-        "import java.util.Set;",
-        "",
-        "@Module",
-        "abstract class EmptySetModule {",
-        "  @Provides @ElementsIntoSet",
-        "  static Set<String> emptySet() { ",
-        "    return Collections.emptySet();",
-        "  }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import com.google.common.util.concurrent.ListenableFuture;",
-        "import dagger.producers.ProductionComponent;",
-        "import java.util.Set;",
-        "",
-        "@ProductionComponent(modules = EmptySetModule.class)",
-        "interface TestComponent {",
-        "  ListenableFuture<Set<String>> strings();",
-        "}");
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-            "package test;",
-            "",
-            "import com.google.common.collect.ImmutableSet;",
-            "import com.google.common.util.concurrent.Futures;",
-            "import com.google.common.util.concurrent.ListenableFuture;",
-            "import dagger.producers.internal.CancellationListener;",
-            "import java.util.Set;",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerTestComponent implements TestComponent, "
-                + "CancellationListener {",
-            "  private DaggerTestComponent() {}",
-            "",
-            "  public static Builder builder() {",
-            "    return new Builder();",
-            "  }",
-            "",
-            "  public static TestComponent create() {",
-            "    return new Builder().build();",
-            "  }",
-            "",
-            "  private Set<String> getSetOfString() {",
-            "    return ImmutableSet.<String>copyOf(",
-            "        EmptySetModule_EmptySetFactory.emptySet());",
-            "  }",
-            "",
-            "  @Override",
-            "  public ListenableFuture<Set<String>> strings() {",
-            "    return Futures.immediateFuture(getSetOfString());",
-            "  }",
-            "",
-            "  @Override",
-            "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {}",
-            "",
-            "  static final class Builder {",
-            "    private Builder() {}",
-            "",
-            "    public TestComponent build() {",
-            "      return new DaggerTestComponent();",
-            "    }",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(emptySetModuleFile, componentFile);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .hasSourceEquivalentTo(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SourceFilesTest.java b/javatests/dagger/internal/codegen/SourceFilesTest.java
deleted file mode 100644
index c7fe998..0000000
--- a/javatests/dagger/internal/codegen/SourceFilesTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 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.truth.Truth.assertThat;
-import static dagger.internal.codegen.SourceFiles.simpleVariableName;
-
-import com.google.testing.compile.CompilationRule;
-import java.util.List;
-import javax.lang.model.element.TypeElement;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link SourceFiles}. */
-@RunWith(JUnit4.class)
-public final class SourceFilesTest {
-  @Rule public CompilationRule compilation = new CompilationRule();
-
-  private TypeElement typeElementFor(Class<?> clazz) {
-    return compilation.getElements().getTypeElement(clazz.getCanonicalName());
-  }
-
-  private static final class Int {}
-
-  @Test
-  public void testSimpleVariableName_typeCollisions() {
-    // a handful of boxed types
-    assertThat(simpleVariableName(typeElementFor(Long.class))).isEqualTo("l");
-    assertThat(simpleVariableName(typeElementFor(Double.class))).isEqualTo("d");
-    // not a boxed type type, but a custom type might collide
-    assertThat(simpleVariableName(typeElementFor(Int.class))).isEqualTo("i");
-    // void is the weird pseudo-boxed type
-    assertThat(simpleVariableName(typeElementFor(Void.class))).isEqualTo("v");
-    // reflective types
-    assertThat(simpleVariableName(typeElementFor(Class.class))).isEqualTo("clazz");
-    assertThat(simpleVariableName(typeElementFor(Package.class))).isEqualTo("pkg");
-  }
-
-  private static final class For {}
-
-  private static final class Goto {}
-
-  @Test
-  public void testSimpleVariableName_randomKeywords() {
-    assertThat(simpleVariableName(typeElementFor(For.class))).isEqualTo("for_");
-    assertThat(simpleVariableName(typeElementFor(Goto.class))).isEqualTo("goto_");
-  }
-
-  @Test
-  public void testSimpleVariableName() {
-    assertThat(simpleVariableName(typeElementFor(Object.class))).isEqualTo("object");
-    assertThat(simpleVariableName(typeElementFor(List.class))).isEqualTo("list");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SubcomponentBuilderValidationTest.java b/javatests/dagger/internal/codegen/SubcomponentBuilderValidationTest.java
deleted file mode 100644
index 5dab4c4..0000000
--- a/javatests/dagger/internal/codegen/SubcomponentBuilderValidationTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.SUBCOMPONENT_BUILDER;
-import static dagger.internal.codegen.ErrorMessages.creatorMessagesFor;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link dagger.Subcomponent.Builder} validation. */
-@RunWith(JUnit4.class)
-public class SubcomponentBuilderValidationTest {
-
-  private static final ErrorMessages.ComponentCreatorMessages MSGS =
-      creatorMessagesFor(SUBCOMPONENT_BUILDER);
-
-  @Test
-  public void testMoreThanOneArgFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {",
-        "    ChildComponent build();",
-        "    Builder set(String s, Integer i);",
-        "    Builder set(Number n, Double d);",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustTakeOneArg())
-        .inFile(childComponentFile)
-        .onLine(10);
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustTakeOneArg())
-        .inFile(childComponentFile)
-        .onLine(11);
-  }
-
-  @Test
-  public void testInheritedMoreThanOneArgFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  interface Parent {",
-        "    ChildComponent build();",
-        "    Builder set1(String s, Integer i);",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  interface Builder extends Parent {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                MSGS.inheritedSetterMethodsMustTakeOneArg(),
-                "set1(java.lang.String,java.lang.Integer)"))
-        .inFile(childComponentFile)
-        .onLine(13);
-  }
-
-  @Test
-  public void testSetterReturningNonVoidOrBuilderFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {",
-        "    ChildComponent build();",
-        "    String set(Integer i);",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.setterMethodsMustReturnVoidOrBuilder())
-        .inFile(childComponentFile)
-        .onLine(10);
-  }
-
-  @Test
-  public void testInheritedSetterReturningNonVoidOrBuilderFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  interface Parent {",
-        "    ChildComponent build();",
-        "    String set(Integer i);",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  interface Builder extends Parent {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                MSGS.inheritedSetterMethodsMustReturnVoidOrBuilder(), "set(java.lang.Integer)"))
-        .inFile(childComponentFile)
-        .onLine(13);
-  }
-
-  @Test
-  public void testGenericsOnSetterMethodFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {",
-        "    ChildComponent build();",
-        "    <T> Builder set(T t);",
-        "  }",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(MSGS.methodsMayNotHaveTypeParameters())
-        .inFile(childComponentFile)
-        .onLine(10);
-  }
-
-  @Test
-  public void testGenericsOnInheritedSetterMethodFails() {
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  interface Parent {",
-        "    ChildComponent build();",
-        "    <T> Builder set(T t);",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  interface Builder extends Parent {}",
-        "}");
-    Compilation compilation = daggerCompiler().compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)"))
-        .inFile(childComponentFile)
-        .onLine(13);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SubcomponentCreatorRequestFulfillmentTest.java b/javatests/dagger/internal/codegen/SubcomponentCreatorRequestFulfillmentTest.java
deleted file mode 100644
index de0067f..0000000
--- a/javatests/dagger/internal/codegen/SubcomponentCreatorRequestFulfillmentTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2017 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.collect.Sets.cartesianProduct;
-import static com.google.common.collect.Sets.immutableEnumSet;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.SUBCOMPONENT_BUILDER;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.SUBCOMPONENT_FACTORY;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.testing.compile.Compilation;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SubcomponentCreatorRequestFulfillmentTest extends ComponentCreatorTestHelper {
-  @Parameters(name = "compilerMode={0}, creatorKind={1}")
-  public static Collection<Object[]> parameters() {
-    Set<List<Object>> params =
-        cartesianProduct(
-            immutableEnumSet(DEFAULT_MODE, FAST_INIT_MODE),
-            immutableEnumSet(SUBCOMPONENT_FACTORY, SUBCOMPONENT_BUILDER));
-    return ImmutableList.copyOf(Iterables.transform(params, Collection::toArray));
-  }
-
-  public SubcomponentCreatorRequestFulfillmentTest(
-      CompilerMode compilerMode, ComponentCreatorAnnotation componentCreatorAnnotation) {
-    super(compilerMode, componentCreatorAnnotation);
-  }
-
-  @Test
-  public void testInlinedSubcomponentCreators_componentMethod() {
-    JavaFileObject subcomponent =
-        preprocessedJavaFile(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Sub build();",
-            "  }",
-            "}");
-    JavaFileObject usesSubcomponent =
-        preprocessedJavaFile(
-            "test.UsesSubcomponent",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class UsesSubcomponent {",
-            "  @Inject UsesSubcomponent(Sub.Builder subBuilder) {}",
-            "}");
-    JavaFileObject component =
-        preprocessedJavaFile(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface C {",
-            "  Sub.Builder sBuilder();",
-            "  UsesSubcomponent usesSubcomponent();",
-            "}");
-
-    JavaFileObject generatedComponent =
-        preprocessedJavaFile(
-            "test.DaggerC",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerC implements C {",
-            "  @Override",
-            "  public Sub.Builder sBuilder() {",
-            "    return new SubBuilder();",
-            "  }",
-            "",
-            "  @Override",
-            "  public UsesSubcomponent usesSubcomponent() {",
-            "    return new UsesSubcomponent(new SubBuilder());",
-            "  }",
-            "",
-            "  private final class SubBuilder implements Sub.Builder {",
-            "    @Override",
-            "    public Sub build() {",
-            "      return new SubImpl();",
-            "    }",
-            "  }",
-            "",
-            "  private final class SubImpl implements Sub {",
-            "    private SubImpl() {}",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(subcomponent, usesSubcomponent, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerC")
-        .containsElementsIn(generatedComponent);
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SubcomponentCreatorValidationTest.java b/javatests/dagger/internal/codegen/SubcomponentCreatorValidationTest.java
deleted file mode 100644
index b5753d4..0000000
--- a/javatests/dagger/internal/codegen/SubcomponentCreatorValidationTest.java
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.SUBCOMPONENT_BUILDER;
-import static dagger.internal.codegen.ComponentCreatorAnnotation.SUBCOMPONENT_FACTORY;
-import static dagger.internal.codegen.ComponentCreatorKind.BUILDER;
-import static dagger.internal.codegen.ComponentCreatorKind.FACTORY;
-import static dagger.internal.codegen.ComponentKind.SUBCOMPONENT;
-import static dagger.internal.codegen.ErrorMessages.ComponentCreatorMessages.moreThanOneRefToSubcomponent;
-import static dagger.internal.codegen.ErrorMessages.componentMessagesFor;
-import static dagger.internal.codegen.TestUtils.message;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for {@link dagger.Subcomponent.Builder} validation. */
-@RunWith(Parameterized.class)
-public class SubcomponentCreatorValidationTest extends ComponentCreatorTestHelper {
-  @Parameters(name = "creatorKind={0}")
-  public static Collection<Object[]> parameters() {
-    return ImmutableList.copyOf(new Object[][] {{SUBCOMPONENT_BUILDER}, {SUBCOMPONENT_FACTORY}});
-  }
-
-  public SubcomponentCreatorValidationTest(ComponentCreatorAnnotation componentCreatorAnnotation) {
-    super(DEFAULT_MODE, componentCreatorAnnotation);
-  }
-
-  @Test
-  public void testRefSubcomponentAndSubCreatorFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent child();",
-        "  ChildComponent.Builder builder();",
-        "}");
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static interface Builder {",
-        "    ChildComponent build();",
-        "  }",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                moreThanOneRefToSubcomponent(),
-                "test.ChildComponent",
-                process("[child(), builder()]")))
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testRefSubCreatorTwiceFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder builder1();",
-        "  ChildComponent.Builder builder2();",
-        "}");
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static interface Builder {",
-        "    ChildComponent build();",
-        "  }",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                moreThanOneRefToSubcomponent(),
-                "test.ChildComponent", process("[builder1(), builder2()]")))
-        .inFile(componentFile);
-  }
-
-  @Test
-  public void testMoreThanOneCreatorFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder1 build();",
-        "}");
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static interface Builder1 {",
-        "    ChildComponent build();",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  static interface Builder2 {",
-        "    ChildComponent build();",
-        "  }",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                componentMessagesFor(SUBCOMPONENT).moreThanOne(),
-                process("[test.ChildComponent.Builder1, test.ChildComponent.Builder2]")))
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testMoreThanOneCreatorFails_differentTypes() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder build();",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static interface Builder {",
-        "    ChildComponent build();",
-        "  }",
-        "",
-        "  @Subcomponent.Factory",
-        "  static interface Factory {",
-        "    ChildComponent create();",
-        "  }",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                componentMessagesFor(SUBCOMPONENT).moreThanOne(),
-                "[test.ChildComponent.Builder, test.ChildComponent.Factory]"))
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorGenericsFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder build();",
-        "}");
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder<T> {",
-        "     ChildComponent build();",
-        "  }",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.generics()).inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorNotInComponentFails() {
-    JavaFileObject builder = preprocessedJavaFile("test.Builder",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent.Builder",
-        "interface Builder {}");
-    Compilation compilation = compile(builder);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.mustBeInComponent()).inFile(builder);
-  }
-
-  @Test
-  public void testCreatorMissingFactoryMethodFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder builder();",
-        "}");
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {}",
-        "}");
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.missingFactoryMethod())
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testPrivateCreatorFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  private interface Builder {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.isPrivate()).inFile(childComponentFile);
-  }
-
-  @Test
-  public void testNonStaticCreatorFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  abstract class Builder {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining(messages.mustBeStatic()).inFile(childComponentFile);
-  }
-
-  @Test
-  public void testNonAbstractCreatorFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static class Builder {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.mustBeAbstract())
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorOneConstructorWithArgsFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static abstract class Builder {",
-        "    Builder(String unused) {}",
-        "  }",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.invalidConstructor())
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorMoreThanOneConstructorFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  static abstract class Builder {",
-        "    Builder() {}",
-        "    Builder(String unused) {}",
-        "  }",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.invalidConstructor())
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorEnumFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  enum Builder {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.mustBeClassOrInterface())
-        .inFile(childComponentFile);
-  }
-
-  @Test
-  public void testCreatorFactoryMethodReturnsWrongTypeFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {",
-        "    String build();",
-        "  }",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(messages.factoryMethodMustReturnComponentType())
-        .inFile(childComponentFile)
-        .onLine(9);
-  }
-
-  @Test
-  public void testInheritedCreatorFactoryMethodReturnsWrongTypeFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  interface Parent {",
-        "    String build();",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  interface Builder extends Parent {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.inheritedFactoryMethodMustReturnComponentType(), process("build")))
-        .inFile(childComponentFile)
-        .onLine(12);
-  }
-
-  @Test
-  public void testTwoFactoryMethodsFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  @Subcomponent.Builder",
-        "  interface Builder {",
-        "    ChildComponent build();",
-        "    ChildComponent build1();",
-        "  }",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(String.format(messages.twoFactoryMethods(), process("build()")))
-        .inFile(childComponentFile)
-        .onLine(10);
-  }
-
-  @Test
-  public void testInheritedTwoFactoryMethodsFails() {
-    JavaFileObject childComponentFile = preprocessedJavaFile("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "abstract class ChildComponent {",
-        "  interface Parent {",
-        "    ChildComponent build();",
-        "    ChildComponent build1();",
-        "  }",
-        "",
-        "  @Subcomponent.Builder",
-        "  interface Builder extends Parent {}",
-        "}");
-    Compilation compilation = compile(childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.inheritedTwoFactoryMethods(), process("build()"), process("build1()")))
-        .inFile(childComponentFile)
-        .onLine(13);
-  }
-
-  @Test
-  public void testMultipleSettersPerTypeFails() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String s() { return \"\"; }",
-            "}");
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  ChildComponent.Builder childComponentBuilder();",
-            "}");
-    JavaFileObject childComponentFile =
-        javaFileBuilder("test.ChildComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Subcomponent;",
-                "import javax.inject.Provider;",
-                "",
-                "@Subcomponent(modules = TestModule.class)",
-                "abstract class ChildComponent {",
-                "  abstract String s();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Subcomponent.Builder",
-                "  interface Builder {",
-                "    ChildComponent build();",
-                "    void set1(TestModule s);",
-                "    void set2(TestModule s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Subcomponent.Factory",
-                "  interface Factory {",
-                "    ChildComponent create(TestModule m1, TestModule m2);",
-                "  }")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(moduleFile, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(BUILDER)
-            ? "[void test.ChildComponent.Builder.set1(test.TestModule), "
-                + "void test.ChildComponent.Builder.set2(test.TestModule)]"
-            : "[test.TestModule m1, test.TestModule m2]";
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.multipleSettersForModuleOrDependencyType(), "test.TestModule", elements))
-        .inFile(childComponentFile)
-        .onLine(11);
-  }
-
-  @Test
-  public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() {
-    JavaFileObject moduleFile =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class TestModule {",
-            "  @Provides String s() { return \"\"; }",
-            "}");
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  ChildComponent.Builder childComponentBuilder();",
-            "}");
-    JavaFileObject childComponentFile =
-        javaFileBuilder("test.ChildComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Subcomponent;",
-                "import javax.inject.Provider;",
-                "",
-                "@Subcomponent(modules = TestModule.class)",
-                "abstract class ChildComponent {",
-                "  abstract String s();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  interface Parent<T> {",
-                "    void set1(T t);",
-                "  }",
-                "",
-                "  @Subcomponent.Builder",
-                "  interface Builder extends Parent<TestModule> {",
-                "    ChildComponent build();",
-                "    void set2(TestModule s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  interface Parent<C, T> {",
-                "    C create(TestModule m1, T t);",
-                "  }",
-                "",
-                "  @Subcomponent.Factory",
-                "  interface Factory extends Parent<ChildComponent, TestModule> {}")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(moduleFile, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(BUILDER)
-            ? "[void test.ChildComponent.Builder.set1(test.TestModule), "
-                + "void test.ChildComponent.Builder.set2(test.TestModule)]"
-            : "[test.TestModule m1, test.TestModule t]";
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.multipleSettersForModuleOrDependencyType(), "test.TestModule", elements))
-        .inFile(childComponentFile)
-        .onLine(15);
-  }
-
-  @Test
-  public void testMultipleSettersPerBoundInstanceTypeFails() {
-    JavaFileObject componentFile =
-        preprocessedJavaFile(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  ChildComponent.Builder childComponentBuilder();",
-            "}");
-    JavaFileObject childComponentFile =
-        javaFileBuilder("test.ChildComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.BindsInstance;",
-                "import dagger.Subcomponent;",
-                "",
-                "@Subcomponent",
-                "abstract class ChildComponent {",
-                "  abstract String s();",
-                "")
-            .addLinesIf(
-                BUILDER,
-                "  @Subcomponent.Builder",
-                "  interface Builder {",
-                "    ChildComponent build();",
-                "    @BindsInstance void set1(String s);",
-                "    @BindsInstance void set2(String s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Subcomponent.Factory",
-                "  interface Factory {",
-                "    ChildComponent create(",
-                "        @BindsInstance String s1, @BindsInstance String s2);",
-                "  }")
-            .addLines( //
-                "}")
-            .build();
-
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    String firstBinding = creatorKind.equals(FACTORY)
-        ? "test.ChildComponent.Factory.create(s1, …)"
-        : "@BindsInstance void test.ChildComponent.Builder.set1(String)";
-    String secondBinding = creatorKind.equals(FACTORY)
-        ? "test.ChildComponent.Factory.create(…, s2)"
-        : "@BindsInstance void test.ChildComponent.Builder.set2(String)";
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "java.lang.String is bound multiple times:",
-                "    " + firstBinding,
-                "    " + secondBinding,
-                "    java.lang.String is provided at",
-                "        test.ChildComponent.s() [test.ParentComponent → test.ChildComponent]"))
-        .inFile(componentFile)
-        .onLineContaining("interface ParentComponent {");
-  }
-
-  @Test
-  public void testExtraSettersFails() {
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder build();",
-        "}");
-    JavaFileObject childComponentFile =
-        javaFileBuilder("test.ChildComponent")
-            .addLines(
-                "package test;",
-                "",
-                "import dagger.Subcomponent;",
-                "import javax.inject.Provider;",
-                "",
-                "@Subcomponent",
-                "abstract class ChildComponent {")
-            .addLinesIf(
-                BUILDER,
-                "  @Subcomponent.Builder",
-                "  interface Builder {",
-                "    ChildComponent build();",
-                "    void set1(String s);",
-                "    void set2(Integer s);",
-                "  }")
-            .addLinesIf(
-                FACTORY,
-                "  @Subcomponent.Factory",
-                "  interface Factory {",
-                "    ChildComponent create(String s, Integer i);",
-                "  }")
-            .addLines( //
-                "}")
-            .build();
-    Compilation compilation = compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    String elements =
-        creatorKind.equals(FACTORY)
-            ? "[String s, Integer i]"
-            : "[void test.ChildComponent.Builder.set1(String),"
-                + " void test.ChildComponent.Builder.set2(Integer)]";
-    assertThat(compilation)
-        .hadErrorContaining(
-            String.format(
-                messages.extraSetters(),
-                elements))
-        .inFile(childComponentFile)
-        .onLine(9);
-  }
-
-  @Test
-  public void testMissingSettersFail() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  TestModule(String unused) {}",
-        "  @Provides String s() { return null; }",
-        "}");
-    JavaFileObject module2File = JavaFileObjects.forSourceLines("test.Test2Module",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class Test2Module {",
-        "  @Provides Integer i() { return null; }",
-        "}");
-    JavaFileObject module3File = JavaFileObjects.forSourceLines("test.Test3Module",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class Test3Module {",
-        "  Test3Module(String unused) {}",
-        "  @Provides Double d() { return null; }",
-        "}");
-    JavaFileObject componentFile = preprocessedJavaFile("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Provider;",
-        "",
-        "@Component",
-        "interface ParentComponent {",
-        "  ChildComponent.Builder build();",
-        "}");
-    JavaFileObject childComponentFile =
-        preprocessedJavaFile(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = {TestModule.class, Test2Module.class, Test3Module.class})",
-            "interface ChildComponent {",
-            "  String string();",
-            "  Integer integer();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    ChildComponent build();",
-            "  }",
-            "}");
-    Compilation compilation =
-        compile(moduleFile, module2File, module3File, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            // Ignores Test2Module because we can construct it ourselves.
-            // TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies.
-            String.format(messages.missingSetters(), "[test.TestModule, test.Test3Module]"))
-        .inFile(childComponentFile)
-        .onLine(11);
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject subcomponent =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface HasSupertype extends Supertype {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Supertype build();",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(foo, supertype, subcomponent);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType_hasNewMethod() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Bar {",
-            "  @Inject Bar() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject subcomponent =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface HasSupertype extends Supertype {",
-            "  Bar bar();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Supertype build();",
-            "  }",
-            "}");
-
-    Compilation compilation = compile(foo, bar, supertype, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining(
-            process(
-                "test.HasSupertype.Builder.build() returns test.Supertype, but test.HasSupertype "
-                    + "declares additional component method(s): bar(). In order to provide "
-                    + "type-safe access to these methods, override build() to return "
-                    + "test.HasSupertype"))
-        .inFile(subcomponent)
-        .onLine(11);
-  }
-
-  @Test
-  public void covariantFactoryMethodReturnType_hasNewMethod_buildMethodInherited() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Bar {",
-            "  @Inject Bar() {}",
-            "}");
-    JavaFileObject supertype =
-        JavaFileObjects.forSourceLines(
-            "test.Supertype",
-            "package test;",
-            "",
-            "interface Supertype {",
-            "  Foo foo();",
-            "}");
-
-    JavaFileObject creatorSupertype =
-        preprocessedJavaFile(
-            "test.CreatorSupertype",
-            "package test;",
-            "",
-            "interface CreatorSupertype {",
-            "  Supertype build();",
-            "}");
-
-    JavaFileObject subcomponent =
-        preprocessedJavaFile(
-            "test.HasSupertype",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface HasSupertype extends Supertype {",
-            "  Bar bar();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder extends CreatorSupertype {}",
-            "}");
-
-    Compilation compilation = compile(foo, bar, supertype, creatorSupertype, subcomponent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .hadWarningContaining(
-            process(
-                "[test.CreatorSupertype.build()] test.HasSupertype.Builder.build() returns "
-                    + "test.Supertype, but test.HasSupertype declares additional component "
-                    + "method(s): bar(). In order to provide type-safe access to these methods, "
-                    + "override build() to return test.HasSupertype"));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SubcomponentValidationTest.java b/javatests/dagger/internal/codegen/SubcomponentValidationTest.java
deleted file mode 100644
index ad08160..0000000
--- a/javatests/dagger/internal/codegen/SubcomponentValidationTest.java
+++ /dev/null
@@ -1,1165 +0,0 @@
-/*
- * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
-import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
-import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
-import static dagger.internal.codegen.Compilers.daggerCompiler;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import java.util.Collection;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SubcomponentValidationTest {
-  @Parameters(name = "{0}")
-  public static Collection<Object[]> parameters() {
-    return CompilerMode.TEST_PARAMETERS;
-  }
-
-  private final CompilerMode compilerMode;
-
-  public SubcomponentValidationTest(CompilerMode compilerMode) {
-    this.compilerMode = compilerMode;
-  }
-
-  @Test public void factoryMethod_missingModulesWithParameters() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  ChildComponent newChildComponent();",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = ModuleWithParameters.class)",
-        "interface ChildComponent {",
-        "  Object object();",
-        "}");
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ModuleWithParameters",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class ModuleWithParameters {",
-        "  private final Object object;",
-        "",
-        "  ModuleWithParameters(Object object) {",
-        "    this.object = object;",
-        "  }",
-        "",
-        "  @Provides Object object() {",
-        "    return object;",
-        "  }",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(componentFile, childComponentFile, moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.ChildComponent requires modules which have no visible default constructors. "
-                + "Add the following modules as parameters to this method: "
-                + "test.ModuleWithParameters")
-        .inFile(componentFile)
-        .onLineContaining("ChildComponent newChildComponent();");
-  }
-
-  @Test
-  public void factoryMethod_grandchild() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  ChildComponent newChildComponent();",
-            "}");
-    JavaFileObject childComponent =
-        JavaFileObjects.forSourceLines(
-            "test.ChildComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface ChildComponent {",
-            "  GrandchildComponent newGrandchildComponent();",
-            "}");
-    JavaFileObject grandchildComponent =
-        JavaFileObjects.forSourceLines(
-            "test.GrandchildComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = GrandchildModule.class)",
-            "interface GrandchildComponent {",
-            "  Object object();",
-            "}");
-    JavaFileObject grandchildModule =
-        JavaFileObjects.forSourceLines(
-            "test.GrandchildModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class GrandchildModule {",
-            "  private final Object object;",
-            "",
-            "  GrandchildModule(Object object) {",
-            "    this.object = object;",
-            "  }",
-            "",
-            "  @Provides Object object() {",
-            "    return object;",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(component, childComponent, grandchildComponent, grandchildModule);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "[test.ChildComponent.newGrandchildComponent()] "
-                + "test.GrandchildComponent requires modules which have no visible default "
-                + "constructors. Add the following modules as parameters to this method: "
-                + "test.GrandchildModule")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test public void factoryMethod_nonModuleParameter() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  ChildComponent newChildComponent(String someRandomString);",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "Subcomponent factory methods may only accept modules, but java.lang.String is not.")
-        .inFile(componentFile)
-        .onLine(7)
-        .atColumn(43);
-  }
-
-  @Test public void factoryMethod_duplicateParameter() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "final class TestModule {}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  ChildComponent newChildComponent(TestModule testModule1, TestModule testModule2);",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = TestModule.class)",
-        "interface ChildComponent {}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(moduleFile, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "A module may only occur once an an argument in a Subcomponent factory method, "
-                + "but test.TestModule was already passed.")
-        .inFile(componentFile)
-        .onLine(7)
-        .atColumn(71);
-  }
-
-  @Test public void factoryMethod_superflouousModule() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "",
-        "@Module",
-        "final class TestModule {}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  ChildComponent newChildComponent(TestModule testModule);",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "interface ChildComponent {}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(moduleFile, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "test.TestModule is present as an argument to the test.ChildComponent factory method, "
-                + "but is not one of the modules used to implement the subcomponent.")
-        .inFile(componentFile)
-        .onLine(7);
-  }
-
-  @Test public void missingBinding() {
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "",
-        "@Module",
-        "final class TestModule {",
-        "  @Provides String provideString(int i) {",
-        "    return Integer.toString(i);",
-        "  }",
-        "}");
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "",
-        "@Component",
-        "interface TestComponent {",
-        "  ChildComponent newChildComponent();",
-        "}");
-    JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = TestModule.class)",
-        "interface ChildComponent {",
-        "  String getString();",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(moduleFile, componentFile, childComponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "java.lang.Integer cannot be provided without an @Inject constructor or an "
-                + "@Provides-annotated method")
-        .inFile(componentFile)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test public void subcomponentOnConcreteType() {
-    JavaFileObject subcomponentFile = JavaFileObjects.forSourceLines("test.NotASubcomponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent",
-        "final class NotASubcomponent {}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(subcomponentFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("interface");
-  }
-
-  @Test public void scopeMismatch() {
-    JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent",
-        "package test;",
-        "",
-        "import dagger.Component;",
-        "import javax.inject.Singleton;",
-        "",
-        "@Component",
-        "@Singleton",
-        "interface ParentComponent {",
-        "  ChildComponent childComponent();",
-        "}");
-    JavaFileObject subcomponentFile = JavaFileObjects.forSourceLines("test.ChildComponent",
-        "package test;",
-        "",
-        "import dagger.Subcomponent;",
-        "",
-        "@Subcomponent(modules = ChildModule.class)",
-        "interface ChildComponent {",
-        "  Object getObject();",
-        "}");
-    JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.ChildModule",
-        "package test;",
-        "",
-        "import dagger.Module;",
-        "import dagger.Provides;",
-        "import javax.inject.Singleton;",
-        "",
-        "@Module",
-        "final class ChildModule {",
-        "  @Provides @Singleton Object provideObject() { return null; }",
-        "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(componentFile, subcomponentFile, moduleFile);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("@Singleton");
-  }
-
-  @Test
-  public void delegateFactoryNotCreatedForSubcomponentWhenProviderExistsInParent() {
-    JavaFileObject parentComponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component",
-            "interface ParentComponent {",
-            "  ChildComponent childComponent();",
-            "  Dep1 getDep1();",
-            "  Dep2 getDep2();",
-            "}");
-    JavaFileObject childComponentFile =
-        JavaFileObjects.forSourceLines(
-            "test.ChildComponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent(modules = ChildModule.class)",
-            "interface ChildComponent {",
-            "  Object getObject();",
-            "}");
-    JavaFileObject childModuleFile =
-        JavaFileObjects.forSourceLines(
-            "test.ChildModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "final class ChildModule {",
-            "  @Provides Object provideObject(A a) { return null; }",
-            "}");
-    JavaFileObject aFile =
-        JavaFileObjects.forSourceLines(
-            "test.A",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class A {",
-            "  @Inject public A(NeedsDep1 a, Dep1 b, Dep2 c) { }",
-            "  @Inject public void methodA() { }",
-            "}");
-    JavaFileObject needsDep1File =
-        JavaFileObjects.forSourceLines(
-            "test.NeedsDep1",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "final class NeedsDep1 {",
-            "  @Inject public NeedsDep1(Dep1 d) { }",
-            "}");
-    JavaFileObject dep1File =
-        JavaFileObjects.forSourceLines(
-            "test.Dep1",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "final class Dep1 {",
-            "  @Inject public Dep1() { }",
-            "  @Inject public void dep1Method() { }",
-            "}");
-    JavaFileObject dep2File =
-        JavaFileObjects.forSourceLines(
-            "test.Dep2",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "final class Dep2 {",
-            "  @Inject public Dep2() { }",
-            "  @Inject public void dep2Method() { }",
-            "}");
-
-    JavaFileObject generatedComponent =
-        compilerMode
-            .javaFileBuilder("test.DaggerParentComponent")
-            .addLines(
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerParentComponent implements ParentComponent {")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.dep1Provider = DoubleCheck.provider(Dep1_Factory.create());",
-                "    this.dep2Provider = DoubleCheck.provider(Dep2_Factory.create());",
-                "  }",
-                "")
-            .addLines(
-                "  @Override", //
-                "  public Dep1 getDep1() {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "   Object local = dep1;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = dep1;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = injectDep1(Dep1_Factory.newInstance());",
-                "          dep1 = DoubleCheck.reentrantCheck(dep1, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (Dep1) local;")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return dep1Provider.get();")
-            .addLines(
-                "  }", //
-                "",
-                "  @Override",
-                "  public Dep2 getDep2() {")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "   Object local = dep2;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = dep2;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = injectDep2(Dep2_Factory.newInstance());",
-                "          dep2 = DoubleCheck.reentrantCheck(dep2, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (Dep2) local;")
-            .addLinesIn(
-                DEFAULT_MODE, //
-                "    return dep2Provider.get();")
-            .addLines(
-                "  }",
-                "",
-                "  @Override",
-                "  public ChildComponent childComponent() {",
-                "    return new ChildComponentImpl();",
-                "  }",
-                "")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "  @CanIgnoreReturnValue",
-                "  private Dep1 injectDep1(Dep1 instance) {",
-                "    Dep1_MembersInjector.injectDep1Method(instance);",
-                "    return instance;",
-                "  }",
-                "",
-                "  @CanIgnoreReturnValue",
-                "  private Dep2 injectDep2(Dep2 instance) {",
-                "    Dep2_MembersInjector.injectDep2Method(instance);",
-                "    return instance;",
-                "  }")
-            .addLines(
-                "",
-                "  private final class ChildComponentImpl implements ChildComponent {",
-                "    private final ChildModule childModule;",
-                "",
-                "    private ChildComponentImpl() {",
-                "      this.childModule = new ChildModule();",
-                "    }",
-                "")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "    private NeedsDep1 getNeedsDep1() {",
-                "      return new NeedsDep1(DaggerParentComponent.this.dep1Provider.get());",
-                "    }")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "    private NeedsDep1 getNeedsDep1() {",
-                "      return new NeedsDep1(DaggerParentComponent.this.getDep1());",
-                "    }")
-            .addLines(
-                "    private A getA() {",
-                "      return injectA(",
-                "          A_Factory.newInstance(",
-                "              getNeedsDep1(),")
-            .addLinesIn(
-                DEFAULT_MODE,
-                "              DaggerParentComponent.this.dep1Provider.get(),",
-                "              DaggerParentComponent.this.dep2Provider.get()));")
-            .addLinesIn(
-                FAST_INIT_MODE,
-                "              DaggerParentComponent.this.getDep1(),",
-                "              DaggerParentComponent.this.getDep2()));")
-            .addLines(
-                "    }",
-                "",
-                "    @Override",
-                "    public Object getObject() {",
-                "      return ChildModule_ProvideObjectFactory.provideObject(",
-                "          childModule, getA());",
-                "    }",
-                "",
-                "    @CanIgnoreReturnValue",
-                "    private A injectA(A instance) {",
-                "      A_MembersInjector.injectMethodA(instance);",
-                "      return instance;",
-                "    }",
-                "  }",
-                "}")
-            .build();
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(
-                parentComponentFile,
-                childComponentFile,
-                childModuleFile,
-                aFile,
-                needsDep1File,
-                dep1File,
-                dep2File);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParentComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void multipleSubcomponentsWithSameSimpleNamesCanExistInSameComponent() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  Foo.Sub newInstanceSubcomponent();",
-            "  NoConflict newNoConflictSubcomponent();",
-            "}");
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "interface Foo {",
-            "  @Subcomponent interface Sub {",
-            "    Bar.Sub newBarSubcomponent();",
-            "  }",
-            "}");
-    JavaFileObject bar =
-        JavaFileObjects.forSourceLines(
-            "test.Bar",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "interface Bar {",
-            "  @Subcomponent interface Sub {",
-            "    test.subpackage.Sub newSubcomponentInSubpackage();",
-            "  }",
-            "}");
-    JavaFileObject baz =
-        JavaFileObjects.forSourceLines(
-            "test.subpackage.Sub",
-            "package test.subpackage;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent public interface Sub {}");
-    JavaFileObject noConflict =
-        JavaFileObjects.forSourceLines(
-            "test.NoConflict",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent interface NoConflict {}");
-
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParentComponent",
-            "package test;",
-            "",
-            "import test.subpackage.Sub;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParentComponent implements ParentComponent {",
-            "  @Override",
-            "  public Foo.Sub newInstanceSubcomponent() {",
-            "    return new F_SubImpl();",
-            "  }",
-            "",
-            "  @Override",
-            "  public NoConflict newNoConflictSubcomponent() {",
-            "    return new NoConflictImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    public ParentComponent build() {",
-            "      return new DaggerParentComponent();",
-            "    }",
-            "  }",
-            "",
-            "  private final class F_SubImpl implements Foo.Sub {",
-            "    @Override",
-            "    public Bar.Sub newBarSubcomponent() {",
-            "      return new B_SubImpl();",
-            "    }",
-            "",
-            "    private final class B_SubImpl implements Bar.Sub {",
-            "      @Override",
-            "      public Sub newSubcomponentInSubpackage() {",
-            "        return new ts_SubImpl();",
-            "      }",
-            "",
-            "      private final class ts_SubImpl implements Sub {}",
-            "    }",
-            "  }",
-            "",
-            "  private final class NoConflictImpl implements NoConflict {}",
-            "}");
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(parent, foo, bar, baz, noConflict);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParentComponent")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void subcomponentSimpleNamesDisambiguated() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  Sub newSubcomponent();",
-            "}");
-    JavaFileObject sub =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent interface Sub {",
-            "  test.deep.many.levels.that.match.test.Sub newDeepSubcomponent();",
-            "}");
-    JavaFileObject deepSub =
-        JavaFileObjects.forSourceLines(
-            "test.deep.many.levels.that.match.test.Sub",
-            "package test.deep.many.levels.that.match.test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent public interface Sub {}");
-
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParentComponent",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParentComponent implements ParentComponent {",
-            "  @Override",
-            "  public Sub newSubcomponent() {",
-            "    return new t_SubImpl();",
-            "  }",
-            "",
-            "  static final class Builder {",
-            "    public ParentComponent build() {",
-            "      return new DaggerParentComponent();",
-            "    }",
-            "  }",
-            "",
-            "  private final class t_SubImpl implements Sub {",
-            "    @Override",
-            "    public test.deep.many.levels.that.match.test.Sub newDeepSubcomponent() {",
-            "      return new tdmltmt_SubImpl();",
-            "    }",
-            "",
-            "    private final class tdmltmt_SubImpl implements ",
-            "        test.deep.many.levels.that.match.test.Sub {",
-            "      private tdmltmt_SubImpl() {}",
-            "    }",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent, sub, deepSub);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParentComponent")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void subcomponentSimpleNamesDisambiguatedInRoot() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "ParentComponent",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  Sub newSubcomponent();",
-            "}");
-    JavaFileObject sub =
-        JavaFileObjects.forSourceLines(
-            "Sub",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent interface Sub {",
-            "  test.deep.many.levels.that.match.test.Sub newDeepSubcomponent();",
-            "}");
-    JavaFileObject deepSub =
-        JavaFileObjects.forSourceLines(
-            "test.deep.many.levels.that.match.test.Sub",
-            "package test.deep.many.levels.that.match.test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent public interface Sub {}");
-
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "DaggerParentComponent",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParentComponent implements ParentComponent {",
-            "  @Override",
-            "  public Sub newSubcomponent() {",
-            "    return new $_SubImpl();",
-            "  }",
-            "",
-            "  private final class $_SubImpl implements Sub {",
-            "    private $_SubImpl() {}",
-            "",
-            "    @Override",
-            "    public test.deep.many.levels.that.match.test.Sub newDeepSubcomponent() {",
-            "      return new tdmltmt_SubImpl();",
-            "    }",
-            "",
-            "    private final class tdmltmt_SubImpl implements ",
-            "        test.deep.many.levels.that.match.test.Sub {",
-            "      private tdmltmt_SubImpl() {}",
-            "    }",
-            "  }",
-            "}",
-            "");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent, sub, deepSub);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("DaggerParentComponent")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void subcomponentImplNameUsesFullyQualifiedClassNameIfNecessary() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.ParentComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface ParentComponent {",
-            "  top1.a.b.c.d.E.F.Sub top1();",
-            "  top2.a.b.c.d.E.F.Sub top2();",
-            "}");
-    JavaFileObject top1 =
-        JavaFileObjects.forSourceLines(
-            "top1.a.b.c.d.E",
-            "package top1.a.b.c.d;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "public interface E {",
-            "  interface F {",
-            "    @Subcomponent interface Sub {}",
-            "  }",
-            "}");
-    JavaFileObject top2 =
-        JavaFileObjects.forSourceLines(
-            "top2.a.b.c.d.E",
-            "package top2.a.b.c.d;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "public interface E {",
-            "  interface F {",
-            "    @Subcomponent interface Sub {}",
-            "  }",
-            "}");
-
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerParentComponent",
-            "package test;",
-            "",
-            "import top1.a.b.c.d.E;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerParentComponent implements ParentComponent {",
-            "  @Override",
-            "  public E.F.Sub top1() {",
-            "    return new F_SubImpl();",
-            "  }",
-            "",
-            "  @Override",
-            "  public top2.a.b.c.d.E.F.Sub top2() {",
-            "    return new F2_SubImpl();",
-            "  }",
-            "",
-            "  private final class F_SubImpl implements E.F.Sub {",
-            "    private F_SubImpl() {}",
-            "  }",
-            "  private final class F2_SubImpl implements top2.a.b.c.d.E.F.Sub {",
-            "    private F2_SubImpl() {}",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent, top1, top2);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerParentComponent")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void parentComponentNameShouldNotBeDisambiguatedWhenItConflictsWithASubcomponent() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface C {",
-            "  test.Foo.C newInstanceC();",
-            "}");
-    JavaFileObject subcomponentWithSameSimpleNameAsParent =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "interface Foo {",
-            "  @Subcomponent interface C {}",
-            "}");
-
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerC",
-            "package test;",
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerC implements C {",
-            "  @Override",
-            "  public Foo.C newInstanceC() {",
-            "    return new F_CImpl();",
-            "  }",
-            "",
-            "  private final class F_CImpl implements Foo.C {}",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(parent, subcomponentWithSameSimpleNameAsParent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerC")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void subcomponentBuilderNamesShouldNotConflict() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.C",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.Subcomponent;",
-            "",
-            "@Component",
-            "interface C {",
-            "  Foo.Sub.Builder fooBuilder();",
-            "  Bar.Sub.Builder barBuilder();",
-            "",
-            "  interface Foo {",
-            "    @Subcomponent",
-            "    interface Sub {",
-            "      @Subcomponent.Builder",
-            "      interface Builder {",
-            "        Sub build();",
-            "      }",
-            "    }",
-            "  }",
-            "",
-            "  interface Bar {",
-            "    @Subcomponent",
-            "    interface Sub {",
-            "      @Subcomponent.Builder",
-            "      interface Builder {",
-            "        Sub build();",
-            "      }",
-            "    }",
-            "  }",
-            "}");
-    JavaFileObject componentGeneratedFile =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerC",
-            "package test;",
-            "",
-            IMPORT_GENERATED_ANNOTATION,
-            "",
-            GENERATED_ANNOTATION,
-            "final class DaggerC implements C {",
-            "  @Override",
-            "  public C.Foo.Sub.Builder fooBuilder() {",
-            "    return new F_SubBuilder();",
-            "  }",
-            "",
-            "  @Override",
-            "  public C.Bar.Sub.Builder barBuilder() {",
-            "    return new B_SubBuilder();",
-            "  }",
-            "",
-            // TODO(user): Reverse the order of subcomponent and builder so that subcomponent
-            // comes first.
-            "  private final class F_SubBuilder implements C.Foo.Sub.Builder {",
-            "    @Override",
-            "    public C.Foo.Sub build() {",
-            "      return new F_SubImpl();",
-            "    }",
-            "  }",
-            "",
-            "  private final class F_SubImpl implements C.Foo.Sub {",
-            "    private F_SubImpl() {}",
-            "  }",
-            "",
-            "  private final class B_SubBuilder implements C.Bar.Sub.Builder {",
-            "    @Override",
-            "    public C.Bar.Sub build() {",
-            "      return new B_SubImpl();",
-            "    }",
-            "  }",
-            "",
-            "  private final class B_SubImpl implements C.Bar.Sub {",
-            "    private B_SubImpl() {}",
-            "  }",
-            "}");
-    Compilation compilation =
-        daggerCompiler().withOptions(compilerMode.javacopts()).compile(parent);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerC")
-        .containsElementsIn(componentGeneratedFile);
-  }
-
-  @Test
-  public void duplicateBindingWithSubcomponentDeclaration() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module(subcomponents = Sub.class)",
-            "class TestModule {",
-            "  @Provides Sub.Builder providesConflictsWithModuleSubcomponents() { return null; }",
-            "  @Provides Object usesSubcomponentBuilder(Sub.Builder builder) {",
-            "    return new Builder().toString();",
-            "  }",
-            "}");
-
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Sub {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Sub build();",
-            "  }",
-            "}");
-
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.Sub",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface C {",
-            "  Object dependsOnBuilder();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler()
-            .withOptions(compilerMode.javacopts())
-            .compile(module, component, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("test.Sub.Builder is bound multiple times:");
-    assertThat(compilation)
-        .hadErrorContaining(
-            "@Provides test.Sub.Builder "
-                + "test.TestModule.providesConflictsWithModuleSubcomponents()");
-    assertThat(compilation)
-        .hadErrorContaining("@Module(subcomponents = test.Sub.class) for test.TestModule");
-  }
-
-  @Test
-  public void subcomponentDependsOnGeneratedType() {
-    JavaFileObject parent =
-        JavaFileObjects.forSourceLines(
-            "test.Parent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface Parent {",
-            "  Child.Builder childBuilder();",
-            "}");
-
-    JavaFileObject child =
-        JavaFileObjects.forSourceLines(
-            "test.Child",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface Child extends ChildSupertype {",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    Child build();",
-            "  }",
-            "}");
-
-    JavaFileObject childSupertype =
-        JavaFileObjects.forSourceLines(
-            "test.ChildSupertype",
-            "package test;",
-            "",
-            "interface ChildSupertype {",
-            "  GeneratedType generatedType();",
-            "}");
-
-    Compilation compilation =
-        daggerCompiler(
-                new GeneratingProcessor(
-                    "test.GeneratedType",
-                    "package test;",
-                    "",
-                    "import javax.inject.Inject;",
-                    "",
-                    "final class GeneratedType {",
-                    "  @Inject GeneratedType() {}",
-                    "}"))
-            .compile(parent, child, childSupertype);
-    assertThat(compilation).succeededWithoutWarnings();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/SwitchingProviderTest.java b/javatests/dagger/internal/codegen/SwitchingProviderTest.java
deleted file mode 100644
index 2898f2e..0000000
--- a/javatests/dagger/internal/codegen/SwitchingProviderTest.java
+++ /dev/null
@@ -1,600 +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.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION;
-
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.Compiler;
-import com.google.testing.compile.JavaFileObjects;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class SwitchingProviderTest {
-  @Test
-  public void switchingProviderTest() {
-    ImmutableList.Builder<JavaFileObject> javaFileObjects = ImmutableList.builder();
-    StringBuilder entryPoints = new StringBuilder();
-    for (int i = 0; i <= 100; i++) {
-      String bindingName = "Binding" + i;
-      javaFileObjects.add(
-          JavaFileObjects.forSourceLines(
-              "test." + bindingName,
-              "package test;",
-              "",
-              "import javax.inject.Inject;",
-              "",
-              "final class " + bindingName + " {",
-              "  @Inject",
-              "  " + bindingName + "() {}",
-              "}"));
-      entryPoints.append(String.format("  Provider<%1$s> get%1$sProvider();\n", bindingName));
-    }
-
-    javaFileObjects.add(
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            entryPoints.toString(),
-            "}"));
-
-    JavaFileObject generatedComponent =
-        JavaFileObjects.forSourceLines(
-            "test.DaggerTestComponent",
-                "package test;",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    private T get0() {",
-                "      switch (id) {",
-                "        case 0:  return (T) new Binding0();",
-                "        case 1:  return (T) new Binding1();",
-                "        case 2:  return (T) new Binding2();",
-                "        case 3:  return (T) new Binding3();",
-                "        case 4:  return (T) new Binding4();",
-                "        case 5:  return (T) new Binding5();",
-                "        case 6:  return (T) new Binding6();",
-                "        case 7:  return (T) new Binding7();",
-                "        case 8:  return (T) new Binding8();",
-                "        case 9:  return (T) new Binding9();",
-                "        case 10: return (T) new Binding10();",
-                "        case 11: return (T) new Binding11();",
-                "        case 12: return (T) new Binding12();",
-                "        case 13: return (T) new Binding13();",
-                "        case 14: return (T) new Binding14();",
-                "        case 15: return (T) new Binding15();",
-                "        case 16: return (T) new Binding16();",
-                "        case 17: return (T) new Binding17();",
-                "        case 18: return (T) new Binding18();",
-                "        case 19: return (T) new Binding19();",
-                "        case 20: return (T) new Binding20();",
-                "        case 21: return (T) new Binding21();",
-                "        case 22: return (T) new Binding22();",
-                "        case 23: return (T) new Binding23();",
-                "        case 24: return (T) new Binding24();",
-                "        case 25: return (T) new Binding25();",
-                "        case 26: return (T) new Binding26();",
-                "        case 27: return (T) new Binding27();",
-                "        case 28: return (T) new Binding28();",
-                "        case 29: return (T) new Binding29();",
-                "        case 30: return (T) new Binding30();",
-                "        case 31: return (T) new Binding31();",
-                "        case 32: return (T) new Binding32();",
-                "        case 33: return (T) new Binding33();",
-                "        case 34: return (T) new Binding34();",
-                "        case 35: return (T) new Binding35();",
-                "        case 36: return (T) new Binding36();",
-                "        case 37: return (T) new Binding37();",
-                "        case 38: return (T) new Binding38();",
-                "        case 39: return (T) new Binding39();",
-                "        case 40: return (T) new Binding40();",
-                "        case 41: return (T) new Binding41();",
-                "        case 42: return (T) new Binding42();",
-                "        case 43: return (T) new Binding43();",
-                "        case 44: return (T) new Binding44();",
-                "        case 45: return (T) new Binding45();",
-                "        case 46: return (T) new Binding46();",
-                "        case 47: return (T) new Binding47();",
-                "        case 48: return (T) new Binding48();",
-                "        case 49: return (T) new Binding49();",
-                "        case 50: return (T) new Binding50();",
-                "        case 51: return (T) new Binding51();",
-                "        case 52: return (T) new Binding52();",
-                "        case 53: return (T) new Binding53();",
-                "        case 54: return (T) new Binding54();",
-                "        case 55: return (T) new Binding55();",
-                "        case 56: return (T) new Binding56();",
-                "        case 57: return (T) new Binding57();",
-                "        case 58: return (T) new Binding58();",
-                "        case 59: return (T) new Binding59();",
-                "        case 60: return (T) new Binding60();",
-                "        case 61: return (T) new Binding61();",
-                "        case 62: return (T) new Binding62();",
-                "        case 63: return (T) new Binding63();",
-                "        case 64: return (T) new Binding64();",
-                "        case 65: return (T) new Binding65();",
-                "        case 66: return (T) new Binding66();",
-                "        case 67: return (T) new Binding67();",
-                "        case 68: return (T) new Binding68();",
-                "        case 69: return (T) new Binding69();",
-                "        case 70: return (T) new Binding70();",
-                "        case 71: return (T) new Binding71();",
-                "        case 72: return (T) new Binding72();",
-                "        case 73: return (T) new Binding73();",
-                "        case 74: return (T) new Binding74();",
-                "        case 75: return (T) new Binding75();",
-                "        case 76: return (T) new Binding76();",
-                "        case 77: return (T) new Binding77();",
-                "        case 78: return (T) new Binding78();",
-                "        case 79: return (T) new Binding79();",
-                "        case 80: return (T) new Binding80();",
-                "        case 81: return (T) new Binding81();",
-                "        case 82: return (T) new Binding82();",
-                "        case 83: return (T) new Binding83();",
-                "        case 84: return (T) new Binding84();",
-                "        case 85: return (T) new Binding85();",
-                "        case 86: return (T) new Binding86();",
-                "        case 87: return (T) new Binding87();",
-                "        case 88: return (T) new Binding88();",
-                "        case 89: return (T) new Binding89();",
-                "        case 90: return (T) new Binding90();",
-                "        case 91: return (T) new Binding91();",
-                "        case 92: return (T) new Binding92();",
-                "        case 93: return (T) new Binding93();",
-                "        case 94: return (T) new Binding94();",
-                "        case 95: return (T) new Binding95();",
-                "        case 96: return (T) new Binding96();",
-                "        case 97: return (T) new Binding97();",
-                "        case 98: return (T) new Binding98();",
-                "        case 99: return (T) new Binding99();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    private T get1() {",
-                "      switch (id) {",
-                "        case 100: return (T) new Binding100();",
-                "        default:  throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id / 100) {",
-                "        case 0:  return get0();",
-                "        case 1:  return get1();",
-                "        default: throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(javaFileObjects.build());
-    assertThat(compilation).succeededWithoutWarnings();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(generatedComponent);
-  }
-
-  @Test
-  public void unscopedBinds() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String s() {",
-            "    return new String();",
-            "  }",
-            "",
-            "  @Binds CharSequence c(String s);",
-            "  @Binds Object o(CharSequence c);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<Object> objectProvider();",
-            "  Provider<CharSequence> charSequenceProvider();",
-            "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private volatile Provider<String> sProvider;",
-                "",
-                "  private Provider<String> getStringProvider() {",
-                "    Object local = sProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      sProvider = (Provider<String>) local;",
-                "    }",
-                "    return (Provider<String>) local;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Object> objectProvider() {",
-                "    return (Provider) getStringProvider();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<CharSequence> charSequenceProvider() {",
-                "    return (Provider) getStringProvider();",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "          return (T) TestModule_SFactory.s();",
-                "        default:",
-                "          throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void scopedBinds() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Binds;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static String s() {",
-            "    return new String();",
-            "  }",
-            "",
-            "  @Binds @Singleton Object o(CharSequence s);",
-            "  @Binds @Singleton CharSequence c(String s);",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Provider;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<Object> objectProvider();",
-            "  Provider<CharSequence> charSequenceProvider();",
-            "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private volatile Object charSequence = new MemoizedSentinel();",
-                "  private volatile Provider<CharSequence> cProvider;",
-                "",
-                "  private CharSequence getCharSequence() {",
-                "    Object local = charSequence;",
-                "    if (local instanceof MemoizedSentinel) {",
-                "      synchronized (local) {",
-                "        local = charSequence;",
-                "        if (local instanceof MemoizedSentinel) {",
-                "          local = TestModule_SFactory.s();",
-                "          charSequence = DoubleCheck.reentrantCheck(charSequence, local);",
-                "        }",
-                "      }",
-                "    }",
-                "    return (CharSequence) local;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Object> objectProvider() {",
-                "    return (Provider) charSequenceProvider();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<CharSequence> charSequenceProvider() {",
-                "    Object local = cProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      cProvider = (Provider<CharSequence>) local;",
-                "    }",
-                "    return (Provider<CharSequence>) local;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0:",
-                "          return (T) DaggerTestComponent.this.getCharSequence();",
-                "        default:",
-                "          throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void emptyMultibindings_avoidSwitchProviders() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.multibindings.Multibinds;",
-            "import dagger.Module;",
-            "import java.util.Map;",
-            "import java.util.Set;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Multibinds Set<String> set();",
-            "  @Multibinds Map<String, String> map();",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Map;",
-            "import java.util.Set;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<Set<String>> setProvider();",
-            "  Provider<Map<String, String>> mapProvider();",
-            "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  @Override",
-                "  public Provider<Set<String>> setProvider() {",
-                "    return SetFactory.<String>empty();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Map<String, String>> mapProvider() {",
-                "    return MapFactory.<String, String>emptyMapProvider();",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void memberInjectors() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "class Foo {}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import dagger.MembersInjector;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  Provider<MembersInjector<Foo>> providerOfMembersInjector();",
-            "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(foo, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  private Provider<MembersInjector<Foo>> fooMembersInjectorProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.fooMembersInjectorProvider = ",
-                "        InstanceFactory.create(MembersInjectors.<Foo>noOp());",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<MembersInjector<Foo>> providerOfMembersInjector() {",
-                "    return fooMembersInjectorProvider;",
-                "  }",
-                "}"));
-  }
-
-  @Test
-  public void optionals() {
-    JavaFileObject present =
-        JavaFileObjects.forSourceLines(
-            "test.Present",
-            "package test;",
-            "",
-            "class Present {}");
-    JavaFileObject absent =
-        JavaFileObjects.forSourceLines(
-            "test.Absent",
-            "package test;",
-            "",
-            "class Absent {}");
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.BindsOptionalOf;",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @BindsOptionalOf Present bindOptionalOfPresent();",
-            "  @BindsOptionalOf Absent bindOptionalOfAbsent();",
-            "",
-            "  @Provides static Present p() { return new Present(); }",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import java.util.Optional;",
-            "import javax.inject.Provider;",
-            "",
-            "@Component(modules = TestModule.class)",
-            "interface TestComponent {",
-            "  Provider<Optional<Present>> providerOfOptionalOfPresent();",
-            "  Provider<Optional<Absent>> providerOfOptionalOfAbsent();",
-            "}");
-
-    Compilation compilation = compilerWithAndroidMode().compile(present, absent, module, component);
-    assertThat(compilation).succeeded();
-    assertThat(compilation)
-        .generatedSourceFile("test.DaggerTestComponent")
-        .containsElementsIn(
-            JavaFileObjects.forSourceLines(
-                "test.DaggerTestComponent",
-                "package test;",
-                "",
-                GENERATED_ANNOTATION,
-                "final class DaggerTestComponent implements TestComponent {",
-                "  @SuppressWarnings(\"rawtypes\")",
-                "  private static final Provider ABSENT_JDK_OPTIONAL_PROVIDER =",
-                "      InstanceFactory.create(Optional.empty());",
-                "",
-                "  private volatile Provider<Optional<Present>> optionalOfPresentProvider;",
-                "",
-                "  private Provider<Optional<Absent>> optionalOfAbsentProvider;",
-                "",
-                "  @SuppressWarnings(\"unchecked\")",
-                "  private void initialize() {",
-                "    this.optionalOfAbsentProvider = absentJdkOptionalProvider();",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Optional<Present>> providerOfOptionalOfPresent() {",
-                "    Object local = optionalOfPresentProvider;",
-                "    if (local == null) {",
-                "      local = new SwitchingProvider<>(0);",
-                "      optionalOfPresentProvider = (Provider<Optional<Present>>) local;",
-                "    }",
-                "    return (Provider<Optional<Present>>) local;",
-                "  }",
-                "",
-                "  @Override",
-                "  public Provider<Optional<Absent>> providerOfOptionalOfAbsent() {",
-                "    return optionalOfAbsentProvider;",
-                "  }",
-                "",
-                "  private static <T> Provider<Optional<T>> absentJdkOptionalProvider() {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    Provider<Optional<T>> provider = ",
-                "          (Provider<Optional<T>>) ABSENT_JDK_OPTIONAL_PROVIDER;",
-                "    return provider;",
-                "  }",
-                "",
-                "  private final class SwitchingProvider<T> implements Provider<T> {",
-                "    @SuppressWarnings(\"unchecked\")",
-                "    @Override",
-                "    public T get() {",
-                "      switch (id) {",
-                "        case 0: // java.util.Optional<test.Present>",
-                "          return (T) Optional.of(TestModule_PFactory.p());",
-                "        default:",
-                "          throw new AssertionError(id);",
-                "      }",
-                "    }",
-                "  }",
-                "}"));
-  }
-
-  private Compiler compilerWithAndroidMode() {
-    return javac()
-        .withProcessors(new ComponentProcessor())
-        .withOptions(CompilerMode.FAST_INIT_MODE.javacopts());
-  }
-}
diff --git a/javatests/dagger/internal/codegen/TestUtils.java b/javatests/dagger/internal/codegen/TestUtils.java
deleted file mode 100644
index 69b27511..0000000
--- a/javatests/dagger/internal/codegen/TestUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.google.common.base.Joiner;
-import java.util.regex.Pattern;
-
-/** Utility methods useful for codegen tests. */
-final class TestUtils {
-
-  private static final Joiner MESSAGE_JOINER = Joiner.on("\n  ");
-
-  /**
-   * Returns the lines joined by {@code "\n  "}. Useful for passing to {@link
-   * com.google.testing.compile.CompilationSubject#hadErrorContaining(String)}, etc.
-   */
-  static String message(String... lines) {
-    return MESSAGE_JOINER.join(lines);
-  }
-
-  /**
-   * Returns a pattern that matches strings that end with the lines joined by {@code "\n  "}. Useful
-   * for passing to {@link
-   * com.google.testing.compile.CompilationSubject#hadErrorContainingMatch(Pattern)}, etc.
-   */
-  static Pattern endsWithMessage(String... lines) {
-    return Pattern.compile(Pattern.quote(message(lines)) + "$");
-  }
-}
diff --git a/javatests/dagger/internal/codegen/TypeProtoConverterTest.java b/javatests/dagger/internal/codegen/TypeProtoConverterTest.java
deleted file mode 100644
index 8c8628c..0000000
--- a/javatests/dagger/internal/codegen/TypeProtoConverterTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019 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.truth.Truth.assertWithMessage;
-import static javax.lang.model.util.ElementFilter.fieldsIn;
-
-import com.google.testing.compile.CompilationRule;
-import dagger.internal.Factory;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import dagger.internal.codegen.serialization.TypeProto;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.lang.model.type.TypeMirror;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests {@link TypeProtoConverter}. */
-@RunWith(JUnit4.class)
-public class TypeProtoConverterTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-
-  private DaggerElements elements;
-  private DaggerTypes types;
-  private TypeProtoConverter typeProtoConverter;
-
-  @Before
-  public void setUp() {
-    this.elements = new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
-    this.types = new DaggerTypes(compilationRule.getTypes(), elements);
-    this.typeProtoConverter = new TypeProtoConverter(types, elements);
-  }
-
-  static class Outer<O> {
-    @SuppressWarnings("ClassCanBeStatic") // We want to specifically test inner classes
-    class Inner<I> {}
-  }
-
-  @SuppressWarnings({"rawtypes", "unused"})
-  static class TypeMirrorConversionSubjects {
-    private Map rawMap;
-    private List<String> listOfString;
-    private List<HashMap<String, Integer>> listOfHashMapOfStringToInteger;
-    private Map<HashMap<String, Integer>, Set<Factory>> mapOfHashMapOfStringToIntegerToSetOfFactory;
-    private Map<HashMap<String, Integer>, Set<Factory>>[][]
-        arrayOfArrayOfMapOfHashMapOfStringToIntegerToSetOfFactory;
-    private Map<HashMap<?, Integer>, ?> mapOfHashMapOfWildcardToIntegerToWildcard;
-    private List<? extends String> listOfWildcardExtendsString;
-    private List<? extends Set<? super String>> listOfWildcardExtendsSetOfWildcardSuperString;
-    private Outer<Object>.Inner<Integer> outerOfObjectDotInnerOfInteger;
-    private List<int[]> listOfIntArray;
-    private List<? extends CharSequence[]> listOfWildcardExtendsCharSequenceArray;
-  }
-
-  @Test
-  public void typeMirrorProtoConversions() {
-    assertProtoConversionEquality(fieldType("rawMap"));
-    assertProtoConversionEquality(fieldType("listOfString"));
-    assertProtoConversionEquality(fieldType("listOfHashMapOfStringToInteger"));
-    assertProtoConversionEquality(fieldType("mapOfHashMapOfStringToIntegerToSetOfFactory"));
-    assertProtoConversionEquality(
-        fieldType("arrayOfArrayOfMapOfHashMapOfStringToIntegerToSetOfFactory"));
-    assertProtoConversionEquality(fieldType("mapOfHashMapOfWildcardToIntegerToWildcard"));
-    assertProtoConversionEquality(fieldType("listOfWildcardExtendsString"));
-    assertProtoConversionEquality(fieldType("listOfWildcardExtendsSetOfWildcardSuperString"));
-    assertProtoConversionEquality(fieldType("outerOfObjectDotInnerOfInteger"));
-    assertProtoConversionEquality(fieldType("listOfIntArray"));
-    assertProtoConversionEquality(fieldType("listOfWildcardExtendsCharSequenceArray"));
-  }
-
-  private TypeMirror fieldType(String fieldName) {
-    return fieldsIn(
-            elements.getTypeElement(TypeMirrorConversionSubjects.class).getEnclosedElements())
-        .stream()
-        .filter(field -> field.getSimpleName().contentEquals(fieldName))
-        .findFirst()
-        .get()
-        .asType();
-  }
-
-  /**
-   * Converts {@link TypeMirror} to a {@link dagger.internal.codegen.serialization.TypeProto} and
-   * back to a {@link TypeMirror}. Asserts that the round-trip conversion is lossless.
-   */
-  private void assertProtoConversionEquality(TypeMirror typeMirror) {
-    TypeProto toProto = TypeProtoConverter.toProto(typeMirror);
-    TypeMirror fromProto = typeProtoConverter.fromProto(toProto);
-    assertWithMessage("expected: %s\nactual  : %s", typeMirror, fromProto)
-        .that(types.isSameType(typeMirror, fromProto))
-        .isTrue();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/ValidationReportTest.java b/javatests/dagger/internal/codegen/ValidationReportTest.java
deleted file mode 100644
index b0f2f2f..0000000
--- a/javatests/dagger/internal/codegen/ValidationReportTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2015 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.truth.Truth.assertThat;
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.internal.codegen.ValidationReport.Builder;
-import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.TypeElement;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ValidationReportTest {
-  private static final JavaFileObject TEST_CLASS_FILE =
-      JavaFileObjects.forSourceLines("test.TestClass",
-          "package test;",
-          "",
-          "final class TestClass {}");
-
-  @Test
-  public void basicReport() {
-    Compilation compilation =
-        javac()
-            .withProcessors(
-                new SimpleTestProcessor() {
-                  @Override
-                  void test() {
-                    Builder<TypeElement> reportBuilder =
-                        ValidationReport.about(getTypeElement("test.TestClass"));
-                    reportBuilder.addError("simple error");
-                    reportBuilder.build().printMessagesTo(processingEnv.getMessager());
-                  }
-                })
-            .compile(TEST_CLASS_FILE);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("simple error").inFile(TEST_CLASS_FILE).onLine(3);
-  }
-
-  @Test
-  public void messageOnDifferentElement() {
-    Compilation compilation =
-        javac()
-            .withProcessors(
-                new SimpleTestProcessor() {
-                  @Override
-                  void test() {
-                    Builder<TypeElement> reportBuilder =
-                        ValidationReport.about(getTypeElement("test.TestClass"));
-                    reportBuilder.addError("simple error", getTypeElement(String.class));
-                    reportBuilder.build().printMessagesTo(processingEnv.getMessager());
-                  }
-                })
-            .compile(TEST_CLASS_FILE);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("[java.lang.String] simple error")
-        .inFile(TEST_CLASS_FILE)
-        .onLine(3);
-  }
-
-  @Test
-  public void subreport() {
-    Compilation compilation =
-        javac()
-            .withProcessors(
-                new SimpleTestProcessor() {
-                  @Override
-                  void test() {
-                    Builder<TypeElement> reportBuilder =
-                        ValidationReport.about(getTypeElement("test.TestClass"));
-                    reportBuilder.addError("simple error");
-                    ValidationReport<TypeElement> parentReport =
-                        ValidationReport.about(getTypeElement(String.class))
-                            .addSubreport(reportBuilder.build())
-                            .build();
-                    assertThat(parentReport.isClean()).isFalse();
-                    parentReport.printMessagesTo(processingEnv.getMessager());
-                  }
-                })
-            .compile(TEST_CLASS_FILE);
-    assertThat(compilation).failed();
-    assertThat(compilation).hadErrorContaining("simple error").inFile(TEST_CLASS_FILE).onLine(3);
-  }
-
-  private static abstract class SimpleTestProcessor extends AbstractProcessor {
-    @Override
-    public Set<String> getSupportedAnnotationTypes() {
-      return ImmutableSet.of("*");
-    }
-
-    @Override
-    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-      test();
-      return false;
-    }
-
-    protected final TypeElement getTypeElement(Class<?> clazz) {
-      return getTypeElement(clazz.getCanonicalName());
-    }
-
-    protected final TypeElement getTypeElement(String canonicalName) {
-      return processingEnv.getElementUtils().getTypeElement(canonicalName);
-    }
-
-    abstract void test();
-  }
-}
diff --git a/javatests/dagger/internal/codegen/javapoet/BUILD b/javatests/dagger/internal/codegen/javapoet/BUILD
deleted file mode 100644
index 99c11bd..0000000
--- a/javatests/dagger/internal/codegen/javapoet/BUILD
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Tests for dagger.internal.codegen.javapoet
-
-package(default_visibility = ["//:src"])
-
-load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "javapoet_tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "//java/dagger/internal/codegen/javapoet",
-        "//java/dagger/internal/codegen/langmodel",
-        "@google_bazel_common//third_party/java/auto:common",
-        "@google_bazel_common//third_party/java/compile_testing",
-        "@google_bazel_common//third_party/java/javapoet",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/internal/codegen/javapoet/CodeBlocksTest.java b/javatests/dagger/internal/codegen/javapoet/CodeBlocksTest.java
deleted file mode 100644
index ee3681e..0000000
--- a/javatests/dagger/internal/codegen/javapoet/CodeBlocksTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 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.javapoet;
-
-import static com.google.common.truth.Truth.assertThat;
-import static dagger.internal.codegen.javapoet.CodeBlocks.javadocLinkTo;
-import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
-import static javax.lang.model.element.ElementKind.METHOD;
-
-import com.google.testing.compile.CompilationRule;
-import com.squareup.javapoet.CodeBlock;
-import java.util.stream.Stream;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.util.Elements;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link CodeBlocks}. */
-@RunWith(JUnit4.class)
-public final class CodeBlocksTest {
-  private static final CodeBlock objectO = CodeBlock.of("$T o", Object.class);
-  private static final CodeBlock stringS = CodeBlock.of("$T s", String.class);
-  private static final CodeBlock intI = CodeBlock.of("$T i", int.class);
-
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-  private Elements elements;
-
-  @Before
-  public void setUp() {
-    this.elements = compilationRule.getElements();
-  }
-
-  @Test
-  public void testToParametersCodeBlock() {
-    assertThat(Stream.of(objectO, stringS, intI).collect(toParametersCodeBlock()))
-        .isEqualTo(CodeBlock.of("$T o, $T s, $T i", Object.class, String.class, int.class));
-  }
-
-  @Test
-  public void testToParametersCodeBlock_empty() {
-    assertThat(Stream.<CodeBlock>of().collect(toParametersCodeBlock())).isEqualTo(CodeBlock.of(""));
-  }
-
-  @Test
-  public void testToParametersCodeBlock_oneElement() {
-    assertThat(Stream.of(objectO).collect(toParametersCodeBlock())).isEqualTo(objectO);
-  }
-
-  @Test
-  public void testJavadocLinkTo() {
-    ExecutableElement equals =
-        elements
-            .getTypeElement(Object.class.getCanonicalName())
-            .getEnclosedElements()
-            .stream()
-            .filter(element -> element.getKind().equals(METHOD))
-            .map(ExecutableElement.class::cast)
-            .filter(method -> method.getSimpleName().contentEquals("equals"))
-            .findFirst()
-            .get();
-    assertThat(javadocLinkTo(equals))
-        .isEqualTo(CodeBlock.of("{@link $T#equals($T)}", Object.class, Object.class));
-  }
-}
diff --git a/javatests/dagger/internal/codegen/javapoet/ExpressionTest.java b/javatests/dagger/internal/codegen/javapoet/ExpressionTest.java
deleted file mode 100644
index acfa460..0000000
--- a/javatests/dagger/internal/codegen/javapoet/ExpressionTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 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.javapoet;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.auto.common.MoreTypes;
-import com.google.testing.compile.CompilationRule;
-import dagger.internal.codegen.langmodel.DaggerElements;
-import dagger.internal.codegen.langmodel.DaggerTypes;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ExpressionTest {
-  @Rule public CompilationRule compilationRule = new CompilationRule();
-  private DaggerElements elements;
-  private DaggerTypes types;
-
-  interface Supertype {}
-
-  interface Subtype extends Supertype {}
-
-  @Before
-  public void setUp() {
-    elements = new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
-    types = new DaggerTypes(compilationRule.getTypes(), elements);
-  }
-
-  @Test
-  public void castTo() {
-    TypeMirror subtype = type(Subtype.class);
-    TypeMirror supertype = type(Supertype.class);
-    Expression expression = Expression.create(subtype, "new $T() {}", subtype);
-
-    Expression castTo = expression.castTo(supertype);
-
-    assertThat(castTo.type()).isSameInstanceAs(supertype);
-    assertThat(castTo.codeBlock().toString())
-        .isEqualTo(
-            "(dagger.internal.codegen.javapoet.ExpressionTest.Supertype) "
-                + "new dagger.internal.codegen.javapoet.ExpressionTest.Subtype() {}");
-  }
-
-  @Test
-  public void box() {
-    PrimitiveType primitiveInt = types.getPrimitiveType(TypeKind.INT);
-
-    Expression primitiveExpression = Expression.create(primitiveInt, "5");
-    Expression boxedExpression = primitiveExpression.box(types);
-
-    assertThat(boxedExpression.codeBlock().toString()).isEqualTo("(java.lang.Integer) 5");
-    assertThat(MoreTypes.equivalence().equivalent(boxedExpression.type(), type(Integer.class)))
-        .isTrue();
-  }
-
-  private TypeMirror type(Class<?> clazz) {
-    return elements.getTypeElement(clazz).asType();
-  }
-}
diff --git a/javatests/dagger/producers/BUILD b/javatests/dagger/producers/BUILD
deleted file mode 100644
index 1e1bd66..0000000
--- a/javatests/dagger/producers/BUILD
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Tests for dagger.producers
-
-package(default_visibility = ["//:src"])
-
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-    "SOURCE_7_TARGET_7",
-)
-load("//:test_defs.bzl", "GenJavaTests")
-
-GenJavaTests(
-    name = "producers_tests",
-    srcs = glob(["**/*.java"]),
-    functional = 0,
-    javacopts = SOURCE_7_TARGET_7 + DOCLINT_REFERENCES + DOCLINT_HTML_AND_SYNTAX,
-    deps = [
-        "//java/dagger/producers",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/guava:testlib",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/mockito",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/producers/ProducedTest.java b/javatests/dagger/producers/ProducedTest.java
deleted file mode 100644
index 5804141..0000000
--- a/javatests/dagger/producers/ProducedTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.testing.EqualsTester;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link Produced}.
- */
-@RunWith(JUnit4.class)
-public class ProducedTest {
-  @Test public void successfulProduced() throws ExecutionException {
-    Object o = new Object();
-    assertThat(Produced.successful(5).get()).isEqualTo(5);
-    assertThat(Produced.successful("monkey").get()).isEqualTo("monkey");
-    assertThat(Produced.successful(o).get()).isSameInstanceAs(o);
-  }
-
-  @Test public void failedProduced() {
-    RuntimeException cause = new RuntimeException("monkey");
-    try {
-      Produced.failed(cause).get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(cause);
-    }
-  }
-
-  @Test public void producedEquivalence() {
-    RuntimeException e1 = new RuntimeException("monkey");
-    RuntimeException e2 = new CancellationException();
-    new EqualsTester()
-        .addEqualityGroup(Produced.successful(132435), Produced.successful(132435))
-        .addEqualityGroup(Produced.successful("hi"), Produced.successful("hi"))
-        .addEqualityGroup(Produced.failed(e1), Produced.failed(e1))
-        .addEqualityGroup(Produced.failed(e2), Produced.failed(e2))
-        .testEquals();
-  }
-}
diff --git a/javatests/dagger/producers/internal/AbstractProducerTest.java b/javatests/dagger/producers/internal/AbstractProducerTest.java
deleted file mode 100644
index da24125..0000000
--- a/javatests/dagger/producers/internal/AbstractProducerTest.java
+++ /dev/null
@@ -1,72 +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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link AbstractProducer}.
- */
-@RunWith(JUnit4.class)
-public class AbstractProducerTest {
-  @Test
-  @SuppressWarnings("CheckReturnValue")
-  public void get_nullPointerException() {
-    Producer<Object> producer = new DelegateProducer<>(null);
-    try {
-      producer.get();
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  @Test public void get() throws Exception {
-    Producer<Integer> producer =
-        new AbstractProducer<Integer>() {
-          int i = 0;
-
-          @Override
-          public ListenableFuture<Integer> compute() {
-            return Futures.immediateFuture(i++);
-          }
-        };
-    assertThat(producer.get().get()).isEqualTo(0);
-    assertThat(producer.get().get()).isEqualTo(0);
-    assertThat(producer.get().get()).isEqualTo(0);
-  }
-
-  static final class DelegateProducer<T> extends AbstractProducer<T> {
-    private final ListenableFuture<T> delegate;
-
-    DelegateProducer(ListenableFuture<T> delegate) {
-      this.delegate = delegate;
-    }
-
-    @Override
-    public ListenableFuture<T> compute() {
-      return delegate;
-    }
-  }
-}
diff --git a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java b/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java
deleted file mode 100644
index b29cb3c..0000000
--- a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java
+++ /dev/null
@@ -1,147 +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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import dagger.producers.Producer;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import javax.inject.Provider;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests {@link AbstractProducer}.
- */
-@RunWith(JUnit4.class)
-public class AbstractProducesMethodProducerTest {
-  @Mock private ProductionComponentMonitor componentMonitor;
-  private ProducerMonitor monitor;
-  private Provider<ProductionComponentMonitor> componentMonitorProvider;
-
-  @Before
-  public void initMocks() {
-    MockitoAnnotations.initMocks(this);
-    monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS);
-    when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor);
-    componentMonitorProvider =
-        new Provider<ProductionComponentMonitor>() {
-          @Override
-          public ProductionComponentMonitor get() {
-            return componentMonitor;
-          }
-        };
-  }
-
-  @Test
-  public void monitor_success() throws Exception {
-    SettableFuture<Integer> delegateFuture = SettableFuture.create();
-    Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture);
-
-    ListenableFuture<Integer> future = producer.get();
-    assertThat(future.isDone()).isFalse();
-    verify(monitor).ready();
-    verify(monitor).requested();
-    verify(monitor).addCallbackTo(anyListenableFuture());
-    verify(monitor).methodStarting();
-    verify(monitor).methodFinished();
-    delegateFuture.set(-42);
-    assertThat(future.get()).isEqualTo(-42);
-    verify(monitor).succeeded(-42);
-    verifyNoMoreInteractions(monitor);
-  }
-
-  @Test
-  public void monitor_failure() throws Exception {
-    SettableFuture<Integer> delegateFuture = SettableFuture.create();
-    Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture);
-
-    ListenableFuture<Integer> future = producer.get();
-    assertThat(future.isDone()).isFalse();
-    verify(monitor).ready();
-    verify(monitor).requested();
-    verify(monitor).addCallbackTo(anyListenableFuture());
-    verify(monitor).methodStarting();
-    verify(monitor).methodFinished();
-    Throwable t = new RuntimeException("monkey");
-    delegateFuture.setException(t);
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(t);
-    }
-    verify(monitor).failed(t);
-    verifyNoMoreInteractions(monitor);
-  }
-
-  private ListenableFuture<?> anyListenableFuture() {
-    return any(ListenableFuture.class);
-  }
-
-  @Test(expected = NullPointerException.class)
-  public void monitor_null() throws Exception {
-    new DelegateProducer<>(null, Futures.immediateFuture(42));
-  }
-
-  static final class DelegateProducer<T> extends AbstractProducesMethodProducer<Void, T> {
-    private final ListenableFuture<T> delegate;
-
-    DelegateProducer(
-        Provider<ProductionComponentMonitor> componentMonitorProvider,
-        ListenableFuture<T> delegate) {
-      super(
-          componentMonitorProvider,
-          null, // token
-          new Provider<Executor>() {
-            @Override
-            public Executor get() {
-              return MoreExecutors.directExecutor();
-            }
-          });
-      this.delegate = delegate;
-    }
-
-    @Override
-    protected ListenableFuture<Void> collectDependencies() {
-      return Futures.immediateFuture(null);
-    }
-
-    @Override
-    protected ListenableFuture<T> callProducesMethod(Void asyncDependencies) {
-      return delegate;
-    }
-  }
-}
diff --git a/javatests/dagger/producers/internal/MapOfProducerProducerTest.java b/javatests/dagger/producers/internal/MapOfProducerProducerTest.java
deleted file mode 100644
index f4be15c..0000000
--- a/javatests/dagger/producers/internal/MapOfProducerProducerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import dagger.producers.Producer;
-import dagger.producers.Producers;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class MapOfProducerProducerTest {
-  @Test
-  public void success() throws Exception {
-    MapOfProducerProducer<Integer, String> mapOfProducerProducer =
-        MapOfProducerProducer.<Integer, String>builder(2)
-            .put(15, Producers.<String>immediateProducer("fifteen"))
-            .put(42, Producers.<String>immediateProducer("forty two"))
-            .build();
-    Map<Integer, Producer<String>> map = mapOfProducerProducer.get().get();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsKey(15);
-    assertThat(map.get(15).get().get()).isEqualTo("fifteen");
-    assertThat(map).containsKey(42);
-    assertThat(map.get(42).get().get()).isEqualTo("forty two");
-  }
-
-  @Test
-  public void failingContributionDoesNotFailMap() throws Exception {
-    RuntimeException cause = new RuntimeException("monkey");
-    MapOfProducerProducer<Integer, String> mapOfProducerProducer =
-        MapOfProducerProducer.<Integer, String>builder(2)
-            .put(15, Producers.<String>immediateProducer("fifteen"))
-            .put(42, Producers.<String>immediateFailedProducer(cause))
-            .build();
-    Map<Integer, Producer<String>> map = mapOfProducerProducer.get().get();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsKey(15);
-    assertThat(map.get(15).get().get()).isEqualTo("fifteen");
-    assertThat(map).containsKey(42);
-    try {
-      map.get(42).get().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(cause);
-    }
-  }
-}
diff --git a/javatests/dagger/producers/internal/MapProducerTest.java b/javatests/dagger/producers/internal/MapProducerTest.java
deleted file mode 100644
index f74bc41..0000000
--- a/javatests/dagger/producers/internal/MapProducerTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import dagger.producers.Producer;
-import dagger.producers.Producers;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class MapProducerTest {
-  @Test
-  public void success() throws Exception {
-    Producer<Map<Integer, String>> mapProducer =
-        MapProducer.<Integer, String>builder(2)
-            .put(15, Producers.immediateProducer("fifteen"))
-            .put(42, Producers.immediateProducer("forty two"))
-            .build();
-    Map<Integer, String> map = mapProducer.get().get();
-    assertThat(map).hasSize(2);
-    assertThat(map).containsEntry(15, "fifteen");
-    assertThat(map).containsEntry(42, "forty two");
-  }
-
-  @Test
-  public void failingContribution() throws Exception {
-    RuntimeException cause = new RuntimeException("monkey");
-    Producer<Map<Integer, String>> mapProducer =
-        MapProducer.<Integer, String>builder(2)
-            .put(15, Producers.immediateProducer("fifteen"))
-            // TODO(ronshapiro): remove the type parameter when we drop java7 support
-            .put(42, Producers.<String>immediateFailedProducer(cause))
-            .build();
-    try {
-      mapProducer.get().get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(cause);
-    }
-  }
-}
diff --git a/javatests/dagger/producers/internal/ProducersTest.java b/javatests/dagger/producers/internal/ProducersTest.java
deleted file mode 100644
index 1cfe121..0000000
--- a/javatests/dagger/producers/internal/ProducersTest.java
+++ /dev/null
@@ -1,143 +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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import javax.inject.Provider;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link Producers}.
- */
-@RunWith(JUnit4.class)
-public class ProducersTest {
-  @Test public void createFutureProduced_success() throws Exception {
-    ListenableFuture<String> future = Futures.immediateFuture("monkey");
-    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
-    assertThat(producedFuture.isDone()).isTrue();
-    assertThat(producedFuture.get().get()).isEqualTo("monkey");
-  }
-
-  @Test public void createFutureProduced_failure() throws Exception {
-    ListenableFuture<String> future = Futures.immediateFailedFuture(new RuntimeException("monkey"));
-    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
-    assertThat(producedFuture.isDone()).isTrue();
-    assertThat(getProducedException(producedFuture.get()))
-        .hasCauseThat()
-        .hasMessageThat()
-        .isEqualTo("monkey");
-  }
-
-  @Test public void createFutureProduced_cancelPropagatesBackwards() throws Exception {
-    ListenableFuture<String> future = SettableFuture.create();
-    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
-    assertThat(producedFuture.isDone()).isFalse();
-    producedFuture.cancel(false);
-    assertThat(future.isCancelled()).isTrue();
-  }
-
-  @Test public void createFutureProduced_cancelDoesNotPropagateForwards() throws Exception {
-    ListenableFuture<String> future = SettableFuture.create();
-    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
-    assertThat(producedFuture.isDone()).isFalse();
-    future.cancel(false);
-    assertThat(producedFuture.isCancelled()).isFalse();
-    assertThat(getProducedException(producedFuture.get()))
-        .hasCauseThat()
-        .isInstanceOf(CancellationException.class);
-  }
-
-  private <T> ExecutionException getProducedException(Produced<T> produced) {
-    try {
-      T value = produced.get();
-      throw new IllegalArgumentException("produced did not throw, but returned " + value);
-    } catch (ExecutionException e) {
-      return e;
-    }
-  }
-
-  @Test public void createFutureSingletonSet_success() throws Exception {
-    ListenableFuture<String> future = Futures.immediateFuture("monkey");
-    ListenableFuture<Set<String>> setFuture = Producers.createFutureSingletonSet(future);
-    assertThat(setFuture.isDone()).isTrue();
-    assertThat(setFuture.get()).containsExactly("monkey");
-  }
-
-  @Test public void createFutureSingletonSet_failure() throws Exception {
-    ListenableFuture<String> future = Futures.immediateFailedFuture(new RuntimeException("monkey"));
-    ListenableFuture<Set<String>> setFuture = Producers.createFutureSingletonSet(future);
-    assertThat(setFuture.isDone()).isTrue();
-    try {
-      setFuture.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("monkey");
-    }
-  }
-
-  @Test
-  public void allAsSet_success() throws Exception {
-    ListenableFuture<Set<String>> future =
-        Producers.allAsSet(
-            ImmutableList.of(
-                Futures.immediateFuture("monkey"), Futures.immediateFuture("gorilla")));
-    assertThat(future.isDone()).isTrue();
-    assertThat(future.get()).containsExactly("monkey", "gorilla");
-  }
-
-  @Test
-  public void allAsSet_failure() throws Exception {
-    ListenableFuture<Set<String>> future =
-        Producers.allAsSet(
-            ImmutableList.of(
-                Futures.immediateFuture("monkey"),
-                Futures.<String>immediateFailedFuture(new RuntimeException("gorilla"))));
-    assertThat(future.isDone()).isTrue();
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("gorilla");
-    }
-  }
-
-  @Test public void producerFromProvider_doesntCache() throws Exception {
-    Producer<Integer> producer = Producers.producerFromProvider(new Provider<Integer>() {
-      int i = 0;
-
-      @Override public Integer get() {
-        return i++;
-      }
-    });
-    assertThat(producer.get().get()).isEqualTo(0);
-    assertThat(producer.get().get()).isEqualTo(1);
-    assertThat(producer.get().get()).isEqualTo(2);
-  }
-}
diff --git a/javatests/dagger/producers/internal/SetOfProducedProducerTest.java b/javatests/dagger/producers/internal/SetOfProducedProducerTest.java
deleted file mode 100644
index 4dffd74..0000000
--- a/javatests/dagger/producers/internal/SetOfProducedProducerTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import dagger.producers.Produced;
-import dagger.producers.Producer;
-import dagger.producers.Producers;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link SetOfProducedProducer}.
- */
-@RunWith(JUnit4.class)
-public class SetOfProducedProducerTest {
-  @Test
-  public void success() throws Exception {
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(1, 1)
-            .addProducer(Producers.immediateProducer(1))
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(5, 7)))
-            .build();
-    assertThat(producer.get().get())
-        .containsExactly(
-            Produced.successful(1),
-            Produced.successful(5),
-            Produced.successful(7));
-  }
-
-  @Test
-  public void failure() throws Exception {
-    RuntimeException e = new RuntimeException("monkey");
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(1, 1)
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)))
-            .addProducer(Producers.<Integer>immediateFailedProducer(e))
-            .build();
-    assertThat(producer.get().get())
-        .containsExactly(
-            Produced.successful(1), Produced.successful(2), Produced.<Integer>failed(e));
-  }
-
-  @Test
-  public void delegateNpe() throws Exception {
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(1, 0)
-            .addProducer(Producers.<Integer>immediateProducer(null))
-            .build();
-    Results<Integer> results = Results.create(producer.get().get());
-    assertThat(results.successes).isEmpty();
-    assertThat(results.failures).hasSize(1);
-    assertThat(Iterables.getOnlyElement(results.failures))
-        .hasCauseThat()
-        .isInstanceOf(NullPointerException.class);
-  }
-
-  @Test
-  public void delegateSetNpe() throws Exception {
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(0, 1)
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(null))
-            .build();
-    Results<Integer> results = Results.create(producer.get().get());
-    assertThat(results.successes).isEmpty();
-    assertThat(results.failures).hasSize(1);
-    assertThat(Iterables.getOnlyElement(results.failures))
-        .hasCauseThat()
-        .isInstanceOf(NullPointerException.class);
-  }
-
-  @Test
-  public void delegateElementNpe() throws Exception {
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(0, 1)
-            .addCollectionProducer(
-                Producers.<Set<Integer>>immediateProducer(Collections.<Integer>singleton(null)))
-            .build();
-    Results<Integer> results = Results.create(producer.get().get());
-    assertThat(results.successes).isEmpty();
-    assertThat(results.failures).hasSize(1);
-    assertThat(Iterables.getOnlyElement(results.failures))
-        .hasCauseThat()
-        .isInstanceOf(NullPointerException.class);
-  }
-
-  @Test
-  public void oneOfDelegateElementNpe() throws Exception {
-    Producer<Set<Produced<Integer>>> producer =
-        SetOfProducedProducer.<Integer>builder(0, 1)
-            .addCollectionProducer(
-                Producers.<Set<Integer>>immediateProducer(
-                    Sets.newHashSet(Arrays.asList(5, 2, null))))
-            .build();
-    Results<Integer> results = Results.create(producer.get().get());
-    assertThat(results.successes).containsExactly(2, 5);
-    assertThat(results.failures).hasSize(1);
-    assertThat(Iterables.getOnlyElement(results.failures))
-        .hasCauseThat()
-        .isInstanceOf(NullPointerException.class);
-  }
-
-  static final class Results<T> {
-    final ImmutableSet<T> successes;
-    final ImmutableSet<ExecutionException> failures;
-
-    private Results(ImmutableSet<T> successes, ImmutableSet<ExecutionException> failures) {
-      this.successes = successes;
-      this.failures = failures;
-    }
-
-    static <T> Results<T> create(Set<Produced<T>> setOfProduced) {
-      ImmutableSet.Builder<T> successes = ImmutableSet.builder();
-      ImmutableSet.Builder<ExecutionException> failures = ImmutableSet.builder();
-      for (Produced<T> produced : setOfProduced) {
-        try {
-          successes.add(produced.get());
-        } catch (ExecutionException e) {
-          failures.add(e);
-        }
-      }
-      return new Results<T>(successes.build(), failures.build());
-    }
-  }
-}
diff --git a/javatests/dagger/producers/internal/SetProducerTest.java b/javatests/dagger/producers/internal/SetProducerTest.java
deleted file mode 100644
index 2bfd51a..0000000
--- a/javatests/dagger/producers/internal/SetProducerTest.java
+++ /dev/null
@@ -1,94 +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.producers.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.ListenableFuture;
-import dagger.producers.Producer;
-import dagger.producers.Producers;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests {@link SetProducer}.
- */
-@RunWith(JUnit4.class)
-public class SetProducerTest {
-  @Test
-  public void success() throws Exception {
-    Producer<Set<Integer>> producer =
-        SetProducer.<Integer>builder(1, 1)
-            .addProducer(Producers.immediateProducer(1))
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(5, 7)))
-            .build();
-    assertThat(producer.get().get()).containsExactly(1, 5, 7);
-  }
-
-  @Test
-  public void delegateNpe() throws Exception {
-    Producer<Set<Integer>> producer =
-        SetProducer.<Integer>builder(1, 0)
-            .addProducer(Producers.<Integer>immediateProducer(null))
-            .build();
-    ListenableFuture<Set<Integer>> future = producer.get();
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(NullPointerException.class);
-    }
-  }
-
-  @Test
-  public void delegateSetNpe() throws Exception {
-    Producer<Set<Integer>> producer =
-        SetProducer.<Integer>builder(0, 1)
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(null))
-            .build();
-    ListenableFuture<Set<Integer>> future = producer.get();
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(NullPointerException.class);
-    }
-  }
-
-  @Test
-  public void delegateElementNpe() throws Exception {
-    Producer<Set<Integer>> producer =
-        SetProducer.<Integer>builder(0, 2)
-            .addCollectionProducer(Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)))
-            .addCollectionProducer(
-                Producers.<Set<Integer>>immediateProducer(Collections.<Integer>singleton(null)))
-            .build();
-    ListenableFuture<Set<Integer>> future = producer.get();
-    try {
-      future.get();
-      fail();
-    } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isInstanceOf(NullPointerException.class);
-    }
-  }
-}
diff --git a/javatests/dagger/producers/monitoring/TimingProductionComponentMonitorTest.java b/javatests/dagger/producers/monitoring/TimingProductionComponentMonitorTest.java
deleted file mode 100644
index 449b5a6..0000000
--- a/javatests/dagger/producers/monitoring/TimingProductionComponentMonitorTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.testing.FakeTicker;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public final class TimingProductionComponentMonitorTest {
-  private static final class ProducerClassA {}
-
-  private static final class ProducerClassB {}
-
-  @Mock private ProductionComponentTimingRecorder.Factory productionComponentTimingRecorderFactory;
-  @Mock private ProductionComponentTimingRecorder productionComponentTimingRecorder;
-  @Mock private ProducerTimingRecorder producerTimingRecorderA;
-  @Mock private ProducerTimingRecorder producerTimingRecorderB;
-
-  private FakeTicker ticker;
-  private ProductionComponentMonitor.Factory monitorFactory;
-
-  @Before
-  public void setUp() {
-    MockitoAnnotations.initMocks(this);
-    when(productionComponentTimingRecorderFactory.create(any(Object.class)))
-        .thenReturn(productionComponentTimingRecorder);
-    when(
-            productionComponentTimingRecorder.producerTimingRecorderFor(
-                ProducerToken.create(ProducerClassA.class)))
-        .thenReturn(producerTimingRecorderA);
-    when(
-            productionComponentTimingRecorder.producerTimingRecorderFor(
-                ProducerToken.create(ProducerClassB.class)))
-        .thenReturn(producerTimingRecorderB);
-    ticker = new FakeTicker();
-    monitorFactory =
-        new TimingProductionComponentMonitor.Factory(
-            productionComponentTimingRecorderFactory, ticker);
-  }
-
-  @Test
-  public void normalExecution_success() {
-    ProductionComponentMonitor monitor = monitorFactory.create(new Object());
-    ProducerMonitor producerMonitorA =
-        monitor.producerMonitorFor(ProducerToken.create(ProducerClassA.class));
-    ticker.advance(5000222);
-    producerMonitorA.methodStarting();
-    ticker.advance(1333);
-    producerMonitorA.methodFinished();
-    ticker.advance(40000555);
-    ProducerMonitor producerMonitorB =
-        monitor.producerMonitorFor(ProducerToken.create(ProducerClassB.class));
-    producerMonitorB.methodStarting();
-    ticker.advance(2000777);
-    producerMonitorA.succeeded(new Object());
-    ticker.advance(3000999);
-    producerMonitorB.methodFinished();
-    ticker.advance(100000222);
-    producerMonitorB.succeeded(new Object());
-
-    verify(producerTimingRecorderA).recordMethod(5000222, 1333);
-    verify(producerTimingRecorderA).recordSuccess(1333 + 40000555 + 2000777);
-    verify(producerTimingRecorderB).recordMethod(5000222 + 1333 + 40000555, 2000777 + 3000999);
-    verify(producerTimingRecorderB).recordSuccess(2000777 + 3000999 + 100000222);
-    verifyNoMoreInteractions(producerTimingRecorderA, producerTimingRecorderB);
-  }
-
-  @Test
-  public void normalExecution_failure() {
-    Throwable failureA = new RuntimeException("monkey");
-    Throwable failureB = new RuntimeException("gorilla");
-    ProductionComponentMonitor monitor = monitorFactory.create(new Object());
-    ProducerMonitor producerMonitorA =
-        monitor.producerMonitorFor(ProducerToken.create(ProducerClassA.class));
-    ticker.advance(5000222);
-    producerMonitorA.methodStarting();
-    ticker.advance(1333);
-    producerMonitorA.methodFinished();
-    ticker.advance(40000555);
-    ProducerMonitor producerMonitorB =
-        monitor.producerMonitorFor(ProducerToken.create(ProducerClassB.class));
-    producerMonitorB.methodStarting();
-    ticker.advance(2000777);
-    producerMonitorA.failed(failureA);
-    ticker.advance(3000999);
-    producerMonitorB.methodFinished();
-    ticker.advance(100000222);
-    producerMonitorB.failed(failureB);
-
-    verify(producerTimingRecorderA).recordMethod(5000222, 1333);
-    verify(producerTimingRecorderA).recordFailure(failureA, 1333 + 40000555 + 2000777);
-    verify(producerTimingRecorderB).recordMethod(5000222 + 1333 + 40000555, 2000777 + 3000999);
-    verify(producerTimingRecorderB).recordFailure(failureB, 2000777 + 3000999 + 100000222);
-    verifyNoMoreInteractions(producerTimingRecorderA, producerTimingRecorderB);
-  }
-}
diff --git a/javatests/dagger/producers/monitoring/TimingRecordersTest.java b/javatests/dagger/producers/monitoring/TimingRecordersTest.java
deleted file mode 100644
index 4e5d74f..0000000
--- a/javatests/dagger/producers/monitoring/TimingRecordersTest.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableList;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public final class TimingRecordersTest {
-  @Mock
-  private ProductionComponentTimingRecorder.Factory mockProductionComponentTimingRecorderFactory;
-
-  @Mock private ProductionComponentTimingRecorder mockProductionComponentTimingRecorder;
-  @Mock private ProducerTimingRecorder mockProducerTimingRecorder;
-
-  @Mock
-  private ProductionComponentTimingRecorder.Factory mockProductionComponentTimingRecorderFactoryA;
-
-  @Mock
-  private ProductionComponentTimingRecorder.Factory mockProductionComponentTimingRecorderFactoryB;
-
-  @Mock
-  private ProductionComponentTimingRecorder.Factory mockProductionComponentTimingRecorderFactoryC;
-
-  @Mock private ProductionComponentTimingRecorder mockProductionComponentTimingRecorderA;
-  @Mock private ProductionComponentTimingRecorder mockProductionComponentTimingRecorderB;
-  @Mock private ProductionComponentTimingRecorder mockProductionComponentTimingRecorderC;
-  @Mock private ProducerTimingRecorder mockProducerTimingRecorderA;
-  @Mock private ProducerTimingRecorder mockProducerTimingRecorderB;
-  @Mock private ProducerTimingRecorder mockProducerTimingRecorderC;
-
-  @Before
-  public void initMocks() {
-    MockitoAnnotations.initMocks(this);
-  }
-
-  @Test
-  public void zeroRecordersReturnsNoOp() {
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.<ProductionComponentTimingRecorder.Factory>of());
-    assertThat(factory)
-        .isSameInstanceAs(TimingRecorders.noOpProductionComponentTimingRecorderFactory());
-  }
-
-  @Test
-  public void singleRecorder_nullProductionComponentTimingRecorder() {
-    when(mockProductionComponentTimingRecorderFactory.create(any(Object.class))).thenReturn(null);
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    assertThat(factory.create(new Object()))
-        .isSameInstanceAs(TimingRecorders.noOpProductionComponentTimingRecorder());
-  }
-
-  @Test
-  public void singleRecorder_throwingProductionComponentTimingRecorderFactory() {
-    when(mockProductionComponentTimingRecorderFactory.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    assertThat(factory.create(new Object()))
-        .isSameInstanceAs(TimingRecorders.noOpProductionComponentTimingRecorder());
-  }
-
-  @Test
-  public void singleRecorder_nullProducerTimingRecorder() {
-    when(mockProductionComponentTimingRecorderFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorder);
-    when(mockProductionComponentTimingRecorder.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(null);
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    assertThat(recorder.producerTimingRecorderFor(ProducerToken.create(Object.class)))
-        .isSameInstanceAs(ProducerTimingRecorder.noOp());
-  }
-
-  @Test
-  public void singleRecorder_throwingProductionComponentTimingRecorder() {
-    when(mockProductionComponentTimingRecorderFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorder);
-    when(mockProductionComponentTimingRecorder.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    assertThat(recorder.producerTimingRecorderFor(ProducerToken.create(Object.class)))
-        .isSameInstanceAs(ProducerTimingRecorder.noOp());
-  }
-
-  @Test
-  public void singleRecorder_normalProducerTimingRecorderSuccess() {
-    setUpNormalSingleRecorder();
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order = inOrder(mockProducerTimingRecorder);
-    order.verify(mockProducerTimingRecorder).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorder).recordSuccess(100);
-    verifyNoMoreInteractions(mockProducerTimingRecorder);
-  }
-
-  @Test
-  public void singleRecorder_normalProducerTimingRecorderFailure() {
-    setUpNormalSingleRecorder();
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-    Throwable t = new RuntimeException("monkey");
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordFailure(t, 100);
-
-    InOrder order = inOrder(mockProducerTimingRecorder);
-    order.verify(mockProducerTimingRecorder).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorder).recordFailure(t, 100);
-    verifyNoMoreInteractions(mockProducerTimingRecorder);
-  }
-
-  @Test
-  public void singleRecorder_throwingProducerTimingRecorderSuccess() {
-    setUpNormalSingleRecorder();
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProducerTimingRecorder)
-        .recordMethod(anyLong(), anyLong());
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProducerTimingRecorder)
-        .recordSuccess(anyLong());
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(mockProductionComponentTimingRecorderFactory));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order = inOrder(mockProducerTimingRecorder);
-    order.verify(mockProducerTimingRecorder).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorder).recordSuccess(100);
-    verifyNoMoreInteractions(mockProducerTimingRecorder);
-  }
-
-  @Test
-  public void multipleRecorders_nullProductionComponentTimingRecorders() {
-    when(mockProductionComponentTimingRecorderFactoryA.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentTimingRecorderFactoryB.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentTimingRecorderFactoryC.create(any(Object.class))).thenReturn(null);
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    assertThat(factory.create(new Object()))
-        .isSameInstanceAs(TimingRecorders.noOpProductionComponentTimingRecorder());
-  }
-
-  @Test
-  public void multipleRecorders_throwingProductionComponentTimingRecorderFactories() {
-    when(mockProductionComponentTimingRecorderFactoryA.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    when(mockProductionComponentTimingRecorderFactoryB.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    when(mockProductionComponentTimingRecorderFactoryC.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    assertThat(factory.create(new Object()))
-        .isSameInstanceAs(TimingRecorders.noOpProductionComponentTimingRecorder());
-  }
-
-  @Test
-  public void multipleRecorders_someNullProductionComponentTimingRecorders() {
-    when(mockProductionComponentTimingRecorderFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorderA);
-    when(mockProductionComponentTimingRecorderFactoryB.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentTimingRecorderFactoryC.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentTimingRecorderA.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorderA);
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order = inOrder(mockProducerTimingRecorderA);
-    order.verify(mockProducerTimingRecorderA).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderA).recordSuccess(100);
-    verifyNoMoreInteractions(mockProducerTimingRecorderA);
-  }
-
-  @Test
-  public void multipleRecorders_someThrowingProductionComponentTimingRecorderFactories() {
-    when(mockProductionComponentTimingRecorderFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorderA);
-    when(mockProductionComponentTimingRecorderFactoryB.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    when(mockProductionComponentTimingRecorderFactoryC.create(any(Object.class)))
-        .thenThrow(new RuntimeException("monkey"));
-    when(mockProductionComponentTimingRecorderA.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorderA);
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order = inOrder(mockProducerTimingRecorderA);
-    order.verify(mockProducerTimingRecorderA).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderA).recordSuccess(100);
-    verifyNoMoreInteractions(mockProducerTimingRecorderA);
-  }
-
-  @Test
-  public void multipleRecorders_normalProductionComponentTimingRecorderSuccess() {
-    setUpNormalMultipleRecorders();
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order =
-        inOrder(
-            mockProducerTimingRecorderA, mockProducerTimingRecorderB, mockProducerTimingRecorderC);
-    order.verify(mockProducerTimingRecorderA).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderB).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderC).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderA).recordSuccess(100);
-    order.verify(mockProducerTimingRecorderB).recordSuccess(100);
-    order.verify(mockProducerTimingRecorderC).recordSuccess(100);
-    verifyNoMoreInteractions(
-        mockProducerTimingRecorderA, mockProducerTimingRecorderB, mockProducerTimingRecorderC);
-  }
-
-  @Test
-  public void multipleRecorders_someThrowingProducerTimingRecordersSuccess() {
-    setUpNormalMultipleRecorders();
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProducerTimingRecorderA)
-        .recordMethod(anyLong(), anyLong());
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProducerTimingRecorderB)
-        .recordSuccess(anyLong());
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProducerTimingRecorderC)
-        .recordMethod(anyLong(), anyLong());
-    ProductionComponentTimingRecorder.Factory factory =
-        TimingRecorders.delegatingProductionComponentTimingRecorderFactory(
-            ImmutableList.of(
-                mockProductionComponentTimingRecorderFactoryA,
-                mockProductionComponentTimingRecorderFactoryB,
-                mockProductionComponentTimingRecorderFactoryC));
-    ProductionComponentTimingRecorder recorder = factory.create(new Object());
-    ProducerTimingRecorder producerTimingRecorder =
-        recorder.producerTimingRecorderFor(ProducerToken.create(Object.class));
-
-    producerTimingRecorder.recordMethod(15, 42);
-    producerTimingRecorder.recordSuccess(100);
-
-    InOrder order =
-        inOrder(
-            mockProducerTimingRecorderA, mockProducerTimingRecorderB, mockProducerTimingRecorderC);
-    order.verify(mockProducerTimingRecorderA).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderB).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderC).recordMethod(15, 42);
-    order.verify(mockProducerTimingRecorderA).recordSuccess(100);
-    order.verify(mockProducerTimingRecorderB).recordSuccess(100);
-    order.verify(mockProducerTimingRecorderC).recordSuccess(100);
-    verifyNoMoreInteractions(
-        mockProducerTimingRecorderA, mockProducerTimingRecorderB, mockProducerTimingRecorderC);
-  }
-
-  private void setUpNormalSingleRecorder() {
-    when(mockProductionComponentTimingRecorderFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorder);
-    when(mockProductionComponentTimingRecorder.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorder);
-  }
-
-  private void setUpNormalMultipleRecorders() {
-    when(mockProductionComponentTimingRecorderFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorderA);
-    when(mockProductionComponentTimingRecorderFactoryB.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorderB);
-    when(mockProductionComponentTimingRecorderFactoryC.create(any(Object.class)))
-        .thenReturn(mockProductionComponentTimingRecorderC);
-    when(mockProductionComponentTimingRecorderA.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorderA);
-    when(mockProductionComponentTimingRecorderB.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorderB);
-    when(mockProductionComponentTimingRecorderC.producerTimingRecorderFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerTimingRecorderC);
-  }
-}
diff --git a/javatests/dagger/producers/monitoring/internal/MonitorsTest.java b/javatests/dagger/producers/monitoring/internal/MonitorsTest.java
deleted file mode 100644
index 47ccccb..0000000
--- a/javatests/dagger/producers/monitoring/internal/MonitorsTest.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (C) 2015 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.producers.monitoring.internal;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableList;
-import dagger.producers.monitoring.ProducerMonitor;
-import dagger.producers.monitoring.ProducerToken;
-import dagger.producers.monitoring.ProductionComponentMonitor;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public final class MonitorsTest {
-  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactory;
-  @Mock private ProductionComponentMonitor mockProductionComponentMonitor;
-  @Mock private ProducerMonitor mockProducerMonitor;
-  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryA;
-  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryB;
-  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryC;
-  @Mock private ProductionComponentMonitor mockProductionComponentMonitorA;
-  @Mock private ProductionComponentMonitor mockProductionComponentMonitorB;
-  @Mock private ProductionComponentMonitor mockProductionComponentMonitorC;
-  @Mock private ProducerMonitor mockProducerMonitorA;
-  @Mock private ProducerMonitor mockProducerMonitorB;
-  @Mock private ProducerMonitor mockProducerMonitorC;
-
-  @Before
-  public void initMocks() {
-    MockitoAnnotations.initMocks(this);
-  }
-
-  @Test
-  public void zeroMonitorsReturnsNoOp() {
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.<ProductionComponentMonitor.Factory>of());
-    assertThat(factory).isSameInstanceAs(ProductionComponentMonitor.Factory.noOp());
-  }
-
-  @Test
-  public void singleMonitor_nullProductionComponentMonitor() {
-    when(mockProductionComponentMonitorFactory.create(any(Object.class))).thenReturn(null);
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    assertThat(factory.create(new Object())).isSameInstanceAs(ProductionComponentMonitor.noOp());
-  }
-
-  @Test
-  public void singleMonitor_throwingProductionComponentMonitorFactory() {
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactory)
-        .create(any(Object.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    assertThat(factory.create(new Object())).isSameInstanceAs(ProductionComponentMonitor.noOp());
-  }
-
-  @Test
-  public void singleMonitor_nullProducerMonitor() {
-    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitor);
-    when(mockProductionComponentMonitor.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(null);
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    assertThat(monitor.producerMonitorFor(ProducerToken.create(Object.class)))
-        .isSameInstanceAs(ProducerMonitor.noOp());
-  }
-
-  @Test
-  public void singleMonitor_throwingProductionComponentMonitor() {
-    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitor);
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitor)
-        .producerMonitorFor(any(ProducerToken.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    assertThat(monitor.producerMonitorFor(ProducerToken.create(Object.class)))
-        .isSameInstanceAs(ProducerMonitor.noOp());
-  }
-
-  @Test
-  public void singleMonitor_normalProducerMonitorSuccess() {
-    setUpNormalSingleMonitor();
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitor);
-    order.verify(mockProducerMonitor).requested();
-    order.verify(mockProducerMonitor).methodStarting();
-    order.verify(mockProducerMonitor).methodFinished();
-    order.verify(mockProducerMonitor).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitor);
-  }
-
-  @Test
-  public void singleMonitor_normalProducerMonitorFailure() {
-    setUpNormalSingleMonitor();
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-    Throwable t = new RuntimeException("monkey");
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.failed(t);
-
-    InOrder order = inOrder(mockProducerMonitor);
-    order.verify(mockProducerMonitor).requested();
-    order.verify(mockProducerMonitor).methodStarting();
-    order.verify(mockProducerMonitor).methodFinished();
-    order.verify(mockProducerMonitor).failed(t);
-    verifyNoMoreInteractions(mockProducerMonitor);
-  }
-
-  @Test
-  public void singleMonitor_throwingProducerMonitorSuccess() {
-    setUpNormalSingleMonitor();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).requested();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).succeeded(any(Object.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitor);
-    order.verify(mockProducerMonitor).requested();
-    order.verify(mockProducerMonitor).methodStarting();
-    order.verify(mockProducerMonitor).methodFinished();
-    order.verify(mockProducerMonitor).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitor);
-  }
-
-  @Test
-  public void singleMonitor_throwingProducerMonitorFailure() {
-    setUpNormalSingleMonitor();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).requested();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).failed(any(Throwable.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(mockProductionComponentMonitorFactory));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-    Throwable t = new RuntimeException("gorilla");
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.failed(t);
-
-    InOrder order = inOrder(mockProducerMonitor);
-    order.verify(mockProducerMonitor).requested();
-    order.verify(mockProducerMonitor).methodStarting();
-    order.verify(mockProducerMonitor).methodFinished();
-    order.verify(mockProducerMonitor).failed(t);
-    verifyNoMoreInteractions(mockProducerMonitor);
-  }
-
-  @Test
-  public void multipleMonitors_nullProductionComponentMonitors() {
-    when(mockProductionComponentMonitorFactoryA.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentMonitorFactoryB.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentMonitorFactoryC.create(any(Object.class))).thenReturn(null);
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    assertThat(factory.create(new Object())).isSameInstanceAs(ProductionComponentMonitor.noOp());
-  }
-
-  @Test
-  public void multipleMonitors_throwingProductionComponentMonitorFactories() {
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactoryA)
-        .create(any(Object.class));
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactoryB)
-        .create(any(Object.class));
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactoryC)
-        .create(any(Object.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    assertThat(factory.create(new Object())).isSameInstanceAs(ProductionComponentMonitor.noOp());
-  }
-
-  @Test
-  public void multipleMonitors_someNullProductionComponentMonitors() {
-    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitorA);
-    when(mockProductionComponentMonitorFactoryB.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentMonitorFactoryC.create(any(Object.class))).thenReturn(null);
-    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitorA);
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitorA);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorA).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitorA);
-  }
-
-  @Test
-  public void multipleMonitors_someThrowingProductionComponentMonitorFactories() {
-    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitorA);
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactoryB)
-        .create(any(Object.class));
-    doThrow(new RuntimeException("monkey"))
-        .when(mockProductionComponentMonitorFactoryC)
-        .create(any(Object.class));
-    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitorA);
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitorA);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorA).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitorA);
-  }
-
-  @Test
-  public void multipleMonitors_normalProductionComponentMonitorSuccess() {
-    setUpNormalMultipleMonitors();
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorB).requested();
-    order.verify(mockProducerMonitorC).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorB).methodStarting();
-    order.verify(mockProducerMonitorC).methodStarting();
-    order.verify(mockProducerMonitorC).methodFinished();
-    order.verify(mockProducerMonitorB).methodFinished();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorC).succeeded(o);
-    order.verify(mockProducerMonitorB).succeeded(o);
-    order.verify(mockProducerMonitorA).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-  }
-
-  @Test
-  public void multipleMonitors_normalProductionComponentMonitorFailure() {
-    setUpNormalMultipleMonitors();
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Throwable t = new RuntimeException("chimpanzee");
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.failed(t);
-
-    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorB).requested();
-    order.verify(mockProducerMonitorC).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorB).methodStarting();
-    order.verify(mockProducerMonitorC).methodStarting();
-    order.verify(mockProducerMonitorC).methodFinished();
-    order.verify(mockProducerMonitorB).methodFinished();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorC).failed(t);
-    order.verify(mockProducerMonitorB).failed(t);
-    order.verify(mockProducerMonitorA).failed(t);
-    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-  }
-
-  @Test
-  public void multipleMonitors_someThrowingProducerMonitorsSuccess() {
-    setUpNormalMultipleMonitors();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).requested();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorC).succeeded(any(Object.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Object o = new Object();
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.succeeded(o);
-
-    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorB).requested();
-    order.verify(mockProducerMonitorC).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorB).methodStarting();
-    order.verify(mockProducerMonitorC).methodStarting();
-    order.verify(mockProducerMonitorC).methodFinished();
-    order.verify(mockProducerMonitorB).methodFinished();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorC).succeeded(o);
-    order.verify(mockProducerMonitorB).succeeded(o);
-    order.verify(mockProducerMonitorA).succeeded(o);
-    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-  }
-
-  @Test
-  public void multipleMonitors_someThrowingProducerMonitorsFailure() {
-    setUpNormalMultipleMonitors();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).requested();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished();
-    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorC).failed(any(Throwable.class));
-    ProductionComponentMonitor.Factory factory =
-        Monitors.delegatingProductionComponentMonitorFactory(
-            ImmutableList.of(
-                mockProductionComponentMonitorFactoryA,
-                mockProductionComponentMonitorFactoryB,
-                mockProductionComponentMonitorFactoryC));
-    ProductionComponentMonitor monitor = factory.create(new Object());
-    ProducerMonitor producerMonitor =
-        monitor.producerMonitorFor(ProducerToken.create(Object.class));
-
-    Throwable t = new RuntimeException("chimpanzee");
-    producerMonitor.requested();
-    producerMonitor.methodStarting();
-    producerMonitor.methodFinished();
-    producerMonitor.failed(t);
-
-    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-    order.verify(mockProducerMonitorA).requested();
-    order.verify(mockProducerMonitorB).requested();
-    order.verify(mockProducerMonitorC).requested();
-    order.verify(mockProducerMonitorA).methodStarting();
-    order.verify(mockProducerMonitorB).methodStarting();
-    order.verify(mockProducerMonitorC).methodStarting();
-    order.verify(mockProducerMonitorC).methodFinished();
-    order.verify(mockProducerMonitorB).methodFinished();
-    order.verify(mockProducerMonitorA).methodFinished();
-    order.verify(mockProducerMonitorC).failed(t);
-    order.verify(mockProducerMonitorB).failed(t);
-    order.verify(mockProducerMonitorA).failed(t);
-    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
-  }
-
-  private void setUpNormalSingleMonitor() {
-    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitor);
-    when(mockProductionComponentMonitor.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitor);
-  }
-
-  private void setUpNormalMultipleMonitors() {
-    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitorA);
-    when(mockProductionComponentMonitorFactoryB.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitorB);
-    when(mockProductionComponentMonitorFactoryC.create(any(Object.class)))
-        .thenReturn(mockProductionComponentMonitorC);
-    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitorA);
-    when(mockProductionComponentMonitorB.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitorB);
-    when(mockProductionComponentMonitorC.producerMonitorFor(any(ProducerToken.class)))
-        .thenReturn(mockProducerMonitorC);
-  }
-}
diff --git a/javatests/dagger/spi/BUILD b/javatests/dagger/spi/BUILD
deleted file mode 100644
index a94461b..0000000
--- a/javatests/dagger/spi/BUILD
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Tests for the Dagger SPI
-
-package(default_visibility = ["//:src"])
-
-load("//:test_defs.bzl", "GenJavaTests")
-load(
-    "//:build_defs.bzl",
-    "DOCLINT_HTML_AND_SYNTAX",
-    "DOCLINT_REFERENCES",
-)
-
-GenJavaTests(
-    name = "spi_tests",
-    srcs = glob(["*.java"]),
-    functional = False,
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = [
-        "//java/dagger:core",
-        "//java/dagger/internal/codegen:processor",
-        "//java/dagger/model",
-        "//java/dagger/spi",
-        "@google_bazel_common//third_party/java/auto:service",
-        "@google_bazel_common//third_party/java/compile_testing",
-        "@google_bazel_common//third_party/java/guava",
-        "@google_bazel_common//third_party/java/jsr330_inject",
-        "@google_bazel_common//third_party/java/junit",
-        "@google_bazel_common//third_party/java/truth",
-    ],
-)
diff --git a/javatests/dagger/spi/FailingPlugin.java b/javatests/dagger/spi/FailingPlugin.java
deleted file mode 100644
index 8fd0e35..0000000
--- a/javatests/dagger/spi/FailingPlugin.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 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.spi;
-
-import static javax.tools.Diagnostic.Kind.ERROR;
-
-import com.google.auto.service.AutoService;
-import com.google.common.collect.ImmutableSet;
-import dagger.model.BindingGraph;
-import java.util.Map;
-import java.util.Set;
-
-@AutoService(BindingGraphPlugin.class)
-public final class FailingPlugin implements BindingGraphPlugin {
-  private Map<String, String> options;
-
-  @Override
-  public Set<String> supportedOptions() {
-    return ImmutableSet.of(
-        "error_on_binding",
-        "error_on_dependency",
-        "error_on_component",
-        "error_on_subcomponents");
-  }
-
-  @Override
-  public void initOptions(Map<String, String> options) {
-    this.options = options;
-  }
-
-  @Override
-  public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
-    if (options.containsKey("error_on_binding")) {
-      String key = options.get("error_on_binding");
-      bindingGraph.bindings().stream()
-          .filter(binding -> binding.key().toString().equals(key))
-          .forEach(
-              binding ->
-                  diagnosticReporter.reportBinding(ERROR, binding, "Bad Binding: %s", binding));
-    }
-
-    if (options.containsKey("error_on_component")) {
-      diagnosticReporter.reportComponent(
-          ERROR,
-          bindingGraph.rootComponentNode(),
-          "Bad Component: %s",
-          bindingGraph.rootComponentNode());
-    }
-
-    if (options.containsKey("error_on_subcomponents")) {
-      bindingGraph.componentNodes().stream()
-          .filter(componentNode -> !componentNode.componentPath().atRoot())
-          .forEach(
-              componentNode ->
-                  diagnosticReporter.reportComponent(
-                      ERROR, componentNode, "Bad Subcomponent: %s", componentNode));
-    }
-
-    if (options.containsKey("error_on_dependency")) {
-      String dependency = options.get("error_on_dependency");
-      bindingGraph.dependencyEdges().stream()
-          .filter(
-              edge ->
-                  edge.dependencyRequest()
-                      .requestElement()
-                      .get()
-                      .getSimpleName()
-                      .contentEquals(dependency))
-          .forEach(
-              edge -> diagnosticReporter.reportDependency(ERROR, edge, "Bad Dependency: %s", edge));
-    }
-
-  }
-
-  @Override
-  public String pluginName() {
-    return "FailingPlugin";
-  }
-}
diff --git a/javatests/dagger/spi/SpiPluginTest.java b/javatests/dagger/spi/SpiPluginTest.java
deleted file mode 100644
index 613a915..0000000
--- a/javatests/dagger/spi/SpiPluginTest.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (C) 2018 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.spi;
-
-import static com.google.testing.compile.CompilationSubject.assertThat;
-import static com.google.testing.compile.Compiler.javac;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.JavaFileObjects;
-import dagger.internal.codegen.ComponentProcessor;
-import javax.tools.JavaFileObject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class SpiPluginTest {
-  @Test
-  public void moduleBinding() {
-    JavaFileObject module =
-        JavaFileObjects.forSourceLines(
-            "test.TestModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "import dagger.Provides;",
-            "",
-            "@Module",
-            "interface TestModule {",
-            "  @Provides",
-            "  static int provideInt() {",
-            "    return 0;",
-            "  }",
-            "}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(new ComponentProcessor())
-            .withOptions(
-                "-Aerror_on_binding=java.lang.Integer", "-Adagger.fullBindingGraphValidation=ERROR")
-            .compile(module);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message("[FailingPlugin] Bad Binding: @Provides int test.TestModule.provideInt()"))
-        .inFile(module)
-        .onLineContaining("interface TestModule");
-  }
-
-  @Test
-  public void dependencyTraceAtBinding() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  Foo foo();",
-            "}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(new ComponentProcessor())
-            .withOptions("-Aerror_on_binding=test.Foo")
-            .compile(component, foo);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Binding: @Inject test.Foo()",
-                "    test.Foo is provided at",
-                "        test.TestComponent.foo()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void dependencyTraceAtDependencyRequest() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo(Duplicated inFooDep) {}",
-            "}");
-    JavaFileObject duplicated =
-        JavaFileObjects.forSourceLines(
-            "test.Duplicated",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Duplicated {",
-            "  @Inject Duplicated() {}",
-            "}");
-    JavaFileObject entryPoint =
-        JavaFileObjects.forSourceLines(
-            "test.EntryPoint",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class EntryPoint {",
-            "  @Inject EntryPoint(Foo foo, Duplicated dup1, Duplicated dup2) {}",
-            "}");
-    JavaFileObject chain1 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain1",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain1 {",
-            "  @Inject Chain1(Chain2 chain) {}",
-            "}");
-    JavaFileObject chain2 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain2",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain2 {",
-            "  @Inject Chain2(Chain3 chain) {}",
-            "}");
-    JavaFileObject chain3 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain3",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain3 {",
-            "  @Inject Chain3(Foo foo) {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  EntryPoint entryPoint();",
-            "  Chain1 chain();",
-            "}");
-
-    CompilationFactory compilationFactory =
-        new CompilationFactory(component, foo, duplicated, entryPoint, chain1, chain2, chain3);
-
-    assertThat(compilationFactory.compilationWithErrorOnDependency("entryPoint"))
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Dependency: test.TestComponent.entryPoint() (entry point)",
-                "    test.EntryPoint is provided at",
-                "        test.TestComponent.entryPoint()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-    assertThat(compilationFactory.compilationWithErrorOnDependency("dup1"))
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Dependency: test.EntryPoint(…, dup1, …)",
-                "    test.Duplicated is injected at",
-                "        test.EntryPoint(…, dup1, …)",
-                "    test.EntryPoint is provided at",
-                "        test.TestComponent.entryPoint()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-    assertThat(compilationFactory.compilationWithErrorOnDependency("dup2"))
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Dependency: test.EntryPoint(…, dup2)",
-                "    test.Duplicated is injected at",
-                "        test.EntryPoint(…, dup2)",
-                "    test.EntryPoint is provided at",
-                "        test.TestComponent.entryPoint()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-
-    Compilation inFooDepCompilation =
-        compilationFactory.compilationWithErrorOnDependency("inFooDep");
-    assertThat(inFooDepCompilation)
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Dependency: test.Foo(inFooDep)",
-                "    test.Duplicated is injected at",
-                "        test.Foo(inFooDep)",
-                "    test.Foo is injected at",
-                "        test.EntryPoint(foo, …)",
-                "    test.EntryPoint is provided at",
-                "        test.TestComponent.entryPoint()",
-                "The following other entry points also depend on it:",
-                "    test.TestComponent.chain()"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void dependencyTraceAtDependencyRequest_subcomponents() {
-    JavaFileObject foo =
-        JavaFileObjects.forSourceLines(
-            "test.Foo",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Foo {",
-            "  @Inject Foo() {}",
-            "}");
-    JavaFileObject entryPoint =
-        JavaFileObjects.forSourceLines(
-            "test.EntryPoint",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class EntryPoint {",
-            "  @Inject EntryPoint(Foo foo) {}",
-            "}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  TestSubcomponent sub();",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface TestSubcomponent {",
-            "  EntryPoint childEntryPoint();",
-            "}");
-
-    CompilationFactory compilationFactory =
-        new CompilationFactory(component, subcomponent, foo, entryPoint);
-    assertThat(compilationFactory.compilationWithErrorOnDependency("childEntryPoint"))
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Dependency: "
-                    + "test.TestSubcomponent.childEntryPoint() (entry point)",
-                "    test.EntryPoint is provided at",
-                "        test.TestSubcomponent.childEntryPoint()"
-                    + " [test.TestComponent → test.TestSubcomponent]"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-    assertThat(compilationFactory.compilationWithErrorOnDependency("foo"))
-        .hadErrorContaining(
-            // TODO(ronshapiro): Maybe make the component path resemble a stack trace:
-            //     test.TestSubcomponent is a child of
-            //         test.TestComponent
-            // TODO(dpb): Or invert the order: Child → Parent
-            message(
-                "[FailingPlugin] Bad Dependency: test.EntryPoint(foo)",
-                "    test.Foo is injected at",
-                "        test.EntryPoint(foo)",
-                "    test.EntryPoint is provided at",
-                "        test.TestSubcomponent.childEntryPoint() "
-                    + "[test.TestComponent → test.TestSubcomponent]"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void errorOnComponent() {
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(new ComponentProcessor())
-            .withOptions("-Aerror_on_component")
-            .compile(component);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining("[FailingPlugin] Bad Component: test.TestComponent")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  @Test
-  public void errorOnSubcomponent() {
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface TestSubcomponent {}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "",
-            "@Component",
-            "interface TestComponent {",
-            "  TestSubcomponent subcomponent();",
-            "}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(new ComponentProcessor())
-            .withOptions("-Aerror_on_subcomponents")
-            .compile(component, subcomponent);
-    assertThat(compilation).failed();
-    assertThat(compilation)
-        .hadErrorContaining(
-            "[FailingPlugin] Bad Subcomponent: test.TestComponent → test.TestSubcomponent "
-                + "[test.TestComponent → test.TestSubcomponent]")
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  // SpiDiagnosticReporter uses a shortest path algorithm to determine a dependency trace to a
-  // binding. Without modifications, this would produce a strange error if a shorter path exists
-  // from one entrypoint, through a @Module.subcomponents builder binding edge, and to the binding
-  // usage within the subcomponent. Therefore, when scanning for the shortest path, we only consider
-  // BindingNodes so we don't cross component boundaries. This test exhibits this case.
-  @Test
-  public void shortestPathToBindingExistsThroughSubcomponentBuilder() {
-    JavaFileObject chain1 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain1",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain1 {",
-            "  @Inject Chain1(Chain2 chain) {}",
-            "}");
-    JavaFileObject chain2 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain2",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain2 {",
-            "  @Inject Chain2(Chain3 chain) {}",
-            "}");
-    JavaFileObject chain3 =
-        JavaFileObjects.forSourceLines(
-            "test.Chain3",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class Chain3 {",
-            "  @Inject Chain3(ExposedOnSubcomponent exposedOnSubcomponent) {}",
-            "}");
-    JavaFileObject exposedOnSubcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.ExposedOnSubcomponent",
-            "package test;",
-            "",
-            "import javax.inject.Inject;",
-            "",
-            "class ExposedOnSubcomponent {",
-            "  @Inject ExposedOnSubcomponent() {}",
-            "}");
-    JavaFileObject subcomponent =
-        JavaFileObjects.forSourceLines(
-            "test.TestSubcomponent",
-            "package test;",
-            "",
-            "import dagger.Subcomponent;",
-            "",
-            "@Subcomponent",
-            "interface TestSubcomponent {",
-            "  ExposedOnSubcomponent exposedOnSubcomponent();",
-            "",
-            "  @Subcomponent.Builder",
-            "  interface Builder {",
-            "    TestSubcomponent build();",
-            "  }",
-            "}");
-    JavaFileObject subcomponentModule =
-        JavaFileObjects.forSourceLines(
-            "test.SubcomponentModule",
-            "package test;",
-            "",
-            "import dagger.Module;",
-            "",
-            "@Module(subcomponents = TestSubcomponent.class)",
-            "interface SubcomponentModule {}");
-    JavaFileObject component =
-        JavaFileObjects.forSourceLines(
-            "test.TestComponent",
-            "package test;",
-            "",
-            "import dagger.Component;",
-            "import javax.inject.Singleton;",
-            "",
-            "@Singleton",
-            "@Component(modules = SubcomponentModule.class)",
-            "interface TestComponent {",
-            "  Chain1 chain();",
-            "  TestSubcomponent.Builder subcomponent();",
-            "}");
-
-    Compilation compilation =
-        javac()
-            .withProcessors(new ComponentProcessor())
-            .withOptions("-Aerror_on_binding=test.ExposedOnSubcomponent")
-            .compile(
-                component,
-                subcomponent,
-                chain1,
-                chain2,
-                chain3,
-                exposedOnSubcomponent,
-                subcomponentModule);
-    assertThat(compilation)
-        .hadErrorContaining(
-            message(
-                "[FailingPlugin] Bad Binding: @Inject test.ExposedOnSubcomponent()",
-                "    test.ExposedOnSubcomponent is injected at",
-                "        test.Chain3(exposedOnSubcomponent)",
-                "    test.Chain3 is injected at",
-                "        test.Chain2(chain)",
-                "    test.Chain2 is injected at",
-                "        test.Chain1(chain)",
-                "    test.Chain1 is provided at",
-                "        test.TestComponent.chain()",
-                "The following other entry points also depend on it:",
-                "    test.TestSubcomponent.exposedOnSubcomponent() "
-                    + "[test.TestComponent → test.TestSubcomponent]"))
-        .inFile(component)
-        .onLineContaining("interface TestComponent");
-  }
-
-  // This works around an issue in the opensource compile testing where only one diagnostic is
-  // recorded per line. When multiple validation items resolve to the same entry point, we can
-  // only see the first. This helper class makes it easier to compile all of the files in the test
-  // multiple times with different options to single out each error
-  private static class CompilationFactory {
-    private final ImmutableList<JavaFileObject> javaFileObjects;
-
-    CompilationFactory(JavaFileObject... javaFileObjects) {
-      this.javaFileObjects = ImmutableList.copyOf(javaFileObjects);
-    }
-
-    private Compilation compilationWithErrorOnDependency(String dependencySimpleName) {
-      return javac()
-          .withProcessors(new ComponentProcessor())
-          .withOptions("-Aerror_on_dependency=" + dependencySimpleName)
-          .compile(javaFileObjects);
-    }
-  }
-
-  private static String message(String... lines) {
-    return Joiner.on("\n  ").join(lines);
-  }
-}
diff --git a/lib/auto-common-0.10-sources.jar b/lib/auto-common-0.10-sources.jar
deleted file mode 100644
index 59bf056..0000000
--- a/lib/auto-common-0.10-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-common-0.10-sources.jar.asc b/lib/auto-common-0.10-sources.jar.asc
deleted file mode 100644
index ecc3339..0000000
--- a/lib/auto-common-0.10-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1
-
-iQEcBAABAgAGBQJaYLeuAAoJEF4feafCmGYeVzIH/A0rkeHli229WFOj5c3HnFqK
-hbyy32JRw8GZXTqNFamkuxWDF03jHwQn0ymp0nxRQ+I3JRTzbfuTnT73e+kiNSI8
-02PowzbrghgsuaifiOGpHaO/FRSBaexzjE1TbZncO6jM8RIg1J7GPqgUenRwA5YT
-7VL7Ig+5G9bXOZMcQ4OuHwqi2O1rSfnSDDIFGlDqmKNiJWHi4KijxNred9CvUGeW
-7zFBOzQkqUqm7Vs2MHmBvNM79fcD1F1SFa2I7+p6/oD1ecC0TAHLdlLhR1/sLBaG
-iw3uQeeflVZ6ilzJg93Rl2kNUw77nnywkt12SY76j1tpF5Ny2l8tid3bBrQEUPE=
-=0e1a
------END PGP SIGNATURE-----
diff --git a/lib/auto-common-0.10-sources.jar.sha1 b/lib/auto-common-0.10-sources.jar.sha1
deleted file mode 100644
index b9b3bee..0000000
--- a/lib/auto-common-0.10-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-913c8de9604380c6e135086132adb26c77fa6c53
\ No newline at end of file
diff --git a/lib/auto-common-0.10.jar b/lib/auto-common-0.10.jar
deleted file mode 100644
index 8cbfa72..0000000
--- a/lib/auto-common-0.10.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-common-0.10.jar.asc b/lib/auto-common-0.10.jar.asc
deleted file mode 100644
index 6d81bdf..0000000
--- a/lib/auto-common-0.10.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1
-
-iQEcBAABAgAGBQJaYLeuAAoJEF4feafCmGYe/1gIAInqdd+9NqxfOKRw6ujpL3nT
-XmmsP9gR/Tvvi3xRKj8PjcO9ydO2IfQ9ySAS6qbKuS9SIQn+Plq+6E+rwYkKy5t/
-MZ7Ff59XgMW0uxFEA2zUbcprgQyR6M4A31MYVmKuZ2fGBs5OsoN0+sZPCDmo4EzN
-TIgZ/LdNUWXLIsIRAKzCnUkYjlnNHKcJbW527obNH0UF/TBARrEAtmfCbKT6f91/
-zl1GtnxNR/9LVRxErFHQPcHrRxVP72xRHjdTCJHsL0t5cJJPr9maqkXq8DAyyptU
-XcjisvelIubTqnBDXcqJBIM3beGYPa5rot+3NjnNbylbfSqMED1dSGJL/fypY/U=
-=5BoX
------END PGP SIGNATURE-----
diff --git a/lib/auto-common-0.10.jar.sha1 b/lib/auto-common-0.10.jar.sha1
deleted file mode 100644
index 2056a80..0000000
--- a/lib/auto-common-0.10.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c8f153ebe04a17183480ab4016098055fb474364
\ No newline at end of file
diff --git a/lib/auto-common-1.0-20151022.071545-39-sources.jar b/lib/auto-common-1.0-20151022.071545-39-sources.jar
new file mode 100644
index 0000000..66b78b0
--- /dev/null
+++ b/lib/auto-common-1.0-20151022.071545-39-sources.jar
Binary files differ
diff --git a/lib/auto-common-1.0-20151022.071545-39.jar b/lib/auto-common-1.0-20151022.071545-39.jar
new file mode 100644
index 0000000..8967dea
--- /dev/null
+++ b/lib/auto-common-1.0-20151022.071545-39.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/auto-common-1.0-20151022.071545-39.jar.txt
similarity index 100%
rename from lib/NOTICE
rename to lib/auto-common-1.0-20151022.071545-39.jar.txt
diff --git a/lib/auto-factory-1.0-20150915.183854-35-sources.jar b/lib/auto-factory-1.0-20150915.183854-35-sources.jar
new file mode 100644
index 0000000..5c12407
--- /dev/null
+++ b/lib/auto-factory-1.0-20150915.183854-35-sources.jar
Binary files differ
diff --git a/lib/auto-factory-1.0-20150915.183854-35.jar b/lib/auto-factory-1.0-20150915.183854-35.jar
new file mode 100644
index 0000000..09f408b
--- /dev/null
+++ b/lib/auto-factory-1.0-20150915.183854-35.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/auto-factory-1.0-20150915.183854-35.jar.txt
similarity index 100%
copy from lib/NOTICE
copy to lib/auto-factory-1.0-20150915.183854-35.jar.txt
diff --git a/lib/auto-factory-1.0-beta6-sources.jar b/lib/auto-factory-1.0-beta6-sources.jar
deleted file mode 100644
index 56c6909..0000000
--- a/lib/auto-factory-1.0-beta6-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-factory-1.0-beta6-sources.jar.asc b/lib/auto-factory-1.0-beta6-sources.jar.asc
deleted file mode 100644
index be05c6e..0000000
--- a/lib/auto-factory-1.0-beta6-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlvN1rYACgkQxR5svH/0
-bwsyngf8C60gBeqMcbTJ05w6IccmLONiVEBfXXVASLGxJRW6A4C6CZCOaeu/JTGV
-RlyKSL4RxT6LdN4IE1k/b+SWwhAGxES6n2J1G9TFq/SiRSEjPL2a41qRynjXo9Sx
-D/jWX4flGS4fT229EDx18d+Vy3So5+jPNLN7KyB4E9yBZfnTTmeENsgvs0Y1jw5D
-MNK73Nwwg+f7R42J+07FauRU8YXPYcG1UYZcnmAeHNDmwfL1UOsfSzrglHbU59mw
-MrupMb3h5VSBZcqknQUBbPQUUWo7e+jSJZKDB750CxBNSBfF3tN2D1vJ1/ynCIDA
-i+iY39xggnIbyKTPj1/aOGTBVfiVJQ==
-=xs9M
------END PGP SIGNATURE-----
diff --git a/lib/auto-factory-1.0-beta6-sources.jar.sha1 b/lib/auto-factory-1.0-beta6-sources.jar.sha1
deleted file mode 100644
index 9b5c0a8..0000000
--- a/lib/auto-factory-1.0-beta6-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-fab31580230ac3001579238a8857a74bd045e3b9
\ No newline at end of file
diff --git a/lib/auto-factory-1.0-beta6.jar b/lib/auto-factory-1.0-beta6.jar
deleted file mode 100644
index e47130f..0000000
--- a/lib/auto-factory-1.0-beta6.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-factory-1.0-beta6.jar.asc b/lib/auto-factory-1.0-beta6.jar.asc
deleted file mode 100644
index 5da4253..0000000
--- a/lib/auto-factory-1.0-beta6.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlvN1rIACgkQxR5svH/0
-bwt0VAf/S4AELEOE7cdcSkSF8vNCUhHgJbyRIb9SLT9Jh6ZXt0sVt1ZMB4Jcx9WL
-GfIwCAZhPcidTF3yVRvK0Sj2zHq53bGNsejL5BLO73oSoVowv7NV96v42zbBtMDU
-K6AI8G7lXEHYDlW4gwiyz/5CjP8VYSJgQ5vuC81rNL0vrBY0S30MlzHmCLjCvE2b
-DpV+thGWluhStwJRwvQArtUDgXYW6BPGetls/Mr0LKiSvz9uS9EvRvcQHiiwqxPu
-Jj5vheKyyeaRq7BOOswoUvfidr+UrNBt/Jit3L2kuo5n4n7sfb6irR610X8mMMN/
-kx5cA78f+p7XHbLZh6w3pySp+HCvKw==
-=1KAq
------END PGP SIGNATURE-----
diff --git a/lib/auto-factory-1.0-beta6.jar.sha1 b/lib/auto-factory-1.0-beta6.jar.sha1
deleted file mode 100644
index 57a5e61..0000000
--- a/lib/auto-factory-1.0-beta6.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-58c804763a4d80c0884ac8a740fcff4d61da72bc
\ No newline at end of file
diff --git a/lib/auto-service-1.0-rc2-sources.jar b/lib/auto-service-1.0-rc2-sources.jar
new file mode 100644
index 0000000..cd8f687
--- /dev/null
+++ b/lib/auto-service-1.0-rc2-sources.jar
Binary files differ
diff --git a/lib/auto-service-1.0-rc2.jar b/lib/auto-service-1.0-rc2.jar
new file mode 100644
index 0000000..ea8fb68
--- /dev/null
+++ b/lib/auto-service-1.0-rc2.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/auto-service-1.0-rc2.jar.txt
similarity index 100%
copy from lib/NOTICE
copy to lib/auto-service-1.0-rc2.jar.txt
diff --git a/lib/auto-service-1.0-rc5-sources.jar b/lib/auto-service-1.0-rc5-sources.jar
deleted file mode 100644
index 8a05c9d..0000000
--- a/lib/auto-service-1.0-rc5-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-service-1.0-rc5-sources.jar.asc b/lib/auto-service-1.0-rc5-sources.jar.asc
deleted file mode 100644
index 08ea732..0000000
--- a/lib/auto-service-1.0-rc5-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlyZH5AACgkQxR5svH/0
-bwuBWwf/QMOlEF0td8ykweHGoOt5B6JmBLk4lPNhZDZdGmvqn+RzbWHo7F5QoBL6
-RQ+Wn97UDroLrIeMRsWvOzL/dA/kMhE2tNX8OKP1kaU7d1ahSkY6PRrPrdcf34IA
-Ku62psSXM5L78HdmhfVpf6UBsa3QJ9ZtLrBMjubxJ7aVrHCTIPP8obVgfgFWHnZD
-nGiynMUNXT6H+L9mDtkWHnVEkC07VBTCFr+6HA3TIf76KQ8LiIj6h+7l6KlPz48h
-eyaElzUUn5deTIG7jrPC2SaVhC0fKu/j1ZazN8tj/25+v9Q9mgZieYYEtiKjrEJU
-tli80ajN26E2NduLldkSVPt6N1Nf/w==
-=6nn7
------END PGP SIGNATURE-----
diff --git a/lib/auto-service-1.0-rc5-sources.jar.sha1 b/lib/auto-service-1.0-rc5-sources.jar.sha1
deleted file mode 100644
index 3638b53..0000000
--- a/lib/auto-service-1.0-rc5-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-76bf7fbfc5a924f13115005a134546c4e2d1b245
\ No newline at end of file
diff --git a/lib/auto-service-1.0-rc5.jar b/lib/auto-service-1.0-rc5.jar
deleted file mode 100644
index 8c43e8f..0000000
--- a/lib/auto-service-1.0-rc5.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-service-1.0-rc5.jar.2 b/lib/auto-service-1.0-rc5.jar.2
deleted file mode 100644
index 8c43e8f..0000000
--- a/lib/auto-service-1.0-rc5.jar.2
+++ /dev/null
Binary files differ
diff --git a/lib/auto-service-1.0-rc5.jar.asc b/lib/auto-service-1.0-rc5.jar.asc
deleted file mode 100644
index e1d0163..0000000
--- a/lib/auto-service-1.0-rc5.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlyZH48ACgkQxR5svH/0
-bwuZSAgAgmJ8gEx+MLtdt8IJY0ZGZtzntCOv2kTmieTQdwLKbmEc/WeQBXZeAWjb
-xKctEnesbNGwJY5jpPBiQH0nDd0MyIOc25gCvug2ezveo9eNe9ptOQFi+4gsG3mv
-0SGD9ZnRkzW8wNyMMWdBUJYdGPJp/FshsOVajBVsMDSev3OBxw8qfT4ZqhTO3LN6
-UnFydeqtbukqBiQRBrWEO7zXDmeHP+6GMWOD4Tkt60VRrSo7Sk6WeUkSJcB0rrmw
-+/blQ3jBlN2/ummOc1dWUu7EyBoWhJhChQDQAuwev5oMMyQnhTLiFcHPvoKWFTlO
-GsBFENSqqxlW4j2ZYpoMX42inuaqbQ==
-=AMUZ
------END PGP SIGNATURE-----
diff --git a/lib/auto-service-1.0-rc5.jar.sha1 b/lib/auto-service-1.0-rc5.jar.sha1
deleted file mode 100644
index 2edbbf4..0000000
--- a/lib/auto-service-1.0-rc5.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d25246bae325b4bcc63b55d6d782515fac32215a
\ No newline at end of file
diff --git a/lib/auto-service-annotations-1.0-rc5-sources.jar b/lib/auto-service-annotations-1.0-rc5-sources.jar
deleted file mode 100644
index 72fd4a9..0000000
--- a/lib/auto-service-annotations-1.0-rc5-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-service-annotations-1.0-rc5-sources.jar.asc b/lib/auto-service-annotations-1.0-rc5-sources.jar.asc
deleted file mode 100644
index 0058623..0000000
--- a/lib/auto-service-annotations-1.0-rc5-sources.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlyZH4IACgkQxR5svH/0
-bwtnEwgAntYeAk/i4kaPhOdKCni4pZpkJ3WcEaDIiZROIvxn3GLFxDp1+WaFOuZS
-kYrqKLmDJdOwEK31FGP/XjsedmB6PP90pp01apaw2XS7pAzXQyNGMOypgCntJsN6
-ZkQYNLum8HQ6XXvEQh9j0eKU/9D+x7DRaxQZ69GkjFS1EwpytEYIEdFsjvHz3SYW
-G15++0H5+l7ZyNjXCs//x6tQ73nqhEu6UylwR4A9YvDuZhpMoFPNvB1+L6mlARgi
-cDRtm8hGLhsNeIYqGmbUEzwwKtKY/n7NwJX1zpXAg86/9E8R1xdbdzfGL6ctqQal
-w3WSYcNnmiZQfPinZuGHnrqDk/rN2w==
-=lgp6
------END PGP SIGNATURE-----
diff --git a/lib/auto-service-annotations-1.0-rc5-sources.jar.sha1 b/lib/auto-service-annotations-1.0-rc5-sources.jar.sha1
deleted file mode 100644
index fc01aa3..0000000
--- a/lib/auto-service-annotations-1.0-rc5-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-a2e50e3ba1f9a88f89142e7ea9a0f5380574f4e4
\ No newline at end of file
diff --git a/lib/auto-service-annotations-1.0-rc5.jar b/lib/auto-service-annotations-1.0-rc5.jar
deleted file mode 100644
index fbc08ab..0000000
--- a/lib/auto-service-annotations-1.0-rc5.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-service-annotations-1.0-rc5.jar.asc b/lib/auto-service-annotations-1.0-rc5.jar.asc
deleted file mode 100644
index b7e43ce..0000000
--- a/lib/auto-service-annotations-1.0-rc5.jar.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQEzBAABCgAdFiEEMoi4voUS1sDKGFJoxR5svH/0bwsFAlyZH4EACgkQxR5svH/0
-bwtNcwf+IvcoHSI7AvrM+z6Lhqes8wEdU9Q59ixakvEos/umjYwCXoGJyAG/w8N5
-4woRDJRg8KgWC0Kls7CGs5ZwplQTLRte/SmXWux8CV0/3v6OlIP4voWvXBueqKST
-gNN/Miy0Qx5uX1Qwh0inqlFF7jOj+IuTofQ4ZM3UjZPLVYhSfS/wTwLmNWNawQq7
-b/PkxaYgC1RuNv9onA8Vru2UCIlH8NFP9iPqPMwhRVVxoSaZzo5NxrRNRPZUfPzF
-GUH/SRDOfXHJ1joeZRK21s8adOGzZZJsSxxZ393xx1jl5qLdoowjTtENgc9gOSQG
-FzxOfWCoWncsJP10KfyYRV70JnJMrQ==
-=dWz/
------END PGP SIGNATURE-----
diff --git a/lib/auto-service-annotations-1.0-rc5.jar.sha1 b/lib/auto-service-annotations-1.0-rc5.jar.sha1
deleted file mode 100644
index 4c48b47..0000000
--- a/lib/auto-service-annotations-1.0-rc5.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6ea999af2b6262a7179a09c51a3d54e7b40a3833
\ No newline at end of file
diff --git a/lib/auto-value-1.4.1-sources.jar b/lib/auto-value-1.4.1-sources.jar
new file mode 100644
index 0000000..c6b307f
--- /dev/null
+++ b/lib/auto-value-1.4.1-sources.jar
Binary files differ
diff --git a/lib/auto-value-1.4.1.jar b/lib/auto-value-1.4.1.jar
new file mode 100644
index 0000000..eeeac6a
--- /dev/null
+++ b/lib/auto-value-1.4.1.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/auto-value-1.4.1.jar.txt
similarity index 100%
copy from lib/NOTICE
copy to lib/auto-value-1.4.1.jar.txt
diff --git a/lib/auto-value-1.6.5-sources.jar b/lib/auto-value-1.6.5-sources.jar
deleted file mode 100644
index 7d08fa7..0000000
--- a/lib/auto-value-1.6.5-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-value-1.6.5-sources.jar.asc b/lib/auto-value-1.6.5-sources.jar.asc
deleted file mode 100644
index 36551c1..0000000
--- a/lib/auto-value-1.6.5-sources.jar.asc
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Comment: GPGTools - https://gpgtools.org
-
-iQEzBAABCgAdFiEEx75bzJ/sFVGM/aiCsPNxD6ZJAOcFAlyuMe0ACgkQsPNxD6ZJ
-AOc+4wgAkYRN5mdnQ54oLb/YGL9jnU7tdcFnq73ddH9wJH9cTGE8dAHIlNT4lEjy
-ligUXdi6YbuAC2Fjs7nMZiSOjEEDlKRozbwE82WOiIdV/MltMJgFCdBbVpszHFmu
-NWxDq5KocdgLODHwmIWJ0Xey6M1rjVZEshNf/U70604eEbGl9Hu0aTVFFVcASMM5
-CC38/X/G72Ja1Cz404WqGpmAsrHgDHdcPUVT3xxDReV1B+yPKxazzuKZA8/+KkWP
-RddLifE3W2NYnLVX49DS9iWCBiEbh5P6jtHvQSiyXIawexhQJGhjQMwHoi0+jHJd
-INp5YyrB64PHqaSgtuXhwgTfXmxkMA==
-=5Cw9
------END PGP SIGNATURE-----
diff --git a/lib/auto-value-1.6.5-sources.jar.md5 b/lib/auto-value-1.6.5-sources.jar.md5
deleted file mode 100644
index ca18ea4..0000000
--- a/lib/auto-value-1.6.5-sources.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-4a433a939d3f77766c785288d5c24c10
\ No newline at end of file
diff --git a/lib/auto-value-1.6.5-sources.jar.sha1 b/lib/auto-value-1.6.5-sources.jar.sha1
deleted file mode 100644
index 17f16a8..0000000
--- a/lib/auto-value-1.6.5-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-bfc251753f9bbdd8855825361d5f8c7fec8a1471
\ No newline at end of file
diff --git a/lib/auto-value-1.6.5.jar b/lib/auto-value-1.6.5.jar
deleted file mode 100644
index be17cd1..0000000
--- a/lib/auto-value-1.6.5.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-value-1.6.5.jar.asc b/lib/auto-value-1.6.5.jar.asc
deleted file mode 100644
index f0cdc39..0000000
--- a/lib/auto-value-1.6.5.jar.asc
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Comment: GPGTools - https://gpgtools.org
-
-iQEzBAABCgAdFiEEx75bzJ/sFVGM/aiCsPNxD6ZJAOcFAlyuMewACgkQsPNxD6ZJ
-AOd5ygf8DOjgClYv8hCaiHiu2mDwFV4s24SbyvSZrAeBrHOoY6/E7leSqilJ+mF9
-3kjDv/VtHTv9Ds2cX2daH5hnvuYIwiCzdze3ZWdKJ+PtWsKpqEAevfEMRmSPPUV4
-ZZ5Zd6VZspD+rUViKfwF8ZW1zjKjdcIPbhuiYR4TF718kPL8WCV2bGruYidjYBoe
-hzLUUqY0rv+IwV+OycbyZwtmx1DVCTkYlDdepSyswr2RGb/UFIf44E0koboI+Xue
-6nF+w6AaOaufjdqe2ObIWNa2tsPTj4KABh3tHmOMs35x367/PzwQmh0I25gFAQrX
-KYo6dYVZeLWmNpdIJxeMIZRok0MAKA==
-=KnCZ
------END PGP SIGNATURE-----
diff --git a/lib/auto-value-1.6.5.jar.md5 b/lib/auto-value-1.6.5.jar.md5
deleted file mode 100644
index 11a5e9d..0000000
--- a/lib/auto-value-1.6.5.jar.md5
+++ /dev/null
@@ -1 +0,0 @@
-d3730b8e2f9c6f62153181618a13f3a2
\ No newline at end of file
diff --git a/lib/auto-value-1.6.5.jar.sha1 b/lib/auto-value-1.6.5.jar.sha1
deleted file mode 100644
index edf62d8..0000000
--- a/lib/auto-value-1.6.5.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-816872c85048f36a67a276ef7a49cc2e4595711c
\ No newline at end of file
diff --git a/lib/auto-value-annotations-1.6.5-sources.jar b/lib/auto-value-annotations-1.6.5-sources.jar
deleted file mode 100644
index b1a8b08..0000000
--- a/lib/auto-value-annotations-1.6.5-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-value-annotations-1.6.5-sources.jar.asc b/lib/auto-value-annotations-1.6.5-sources.jar.asc
deleted file mode 100644
index 81a4515..0000000
--- a/lib/auto-value-annotations-1.6.5-sources.jar.asc
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Comment: GPGTools - https://gpgtools.org
-
-iQEzBAABCgAdFiEEx75bzJ/sFVGM/aiCsPNxD6ZJAOcFAlyuMdUACgkQsPNxD6ZJ
-AOfNYwgAqoJ9hi7JyS1iwf646TPLPbtRaaRzl/w9hrZntVlMiHL5Ov+LHq6WW1tS
-IWqz9K6dbEDW4O3WbNXUsiWTGzUvkNc/bjQOY4MTCthTj/LO9PqHVSDGgWo/Y37c
-jazTbUNxctFSziu9mVZdw1VdCI65LVCbhSaOeIc7Msmr/ALtZ1pBGdJ8dzxuC3Dl
-BeT2khADj7C13Kicu7QtZfZypbTqB6JnjAwMO56c4pRviIqRpJsOKHbJM1KBxms+
-6JGv63XTBP22f83XX38wAAPocT5NZBn+lZcDcbC6Mh0NIhaISdx73ujWtTwHX5fC
-x0NYKIIBdyEb5GkPeD1D/IjB4w8o5w==
-=Hbou
------END PGP SIGNATURE-----
diff --git a/lib/auto-value-annotations-1.6.5-sources.jar.sha1 b/lib/auto-value-annotations-1.6.5-sources.jar.sha1
deleted file mode 100644
index 897752c..0000000
--- a/lib/auto-value-annotations-1.6.5-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-3499fd80025705c502699d1154c4b9631cb7a95e
\ No newline at end of file
diff --git a/lib/auto-value-annotations-1.6.5.jar b/lib/auto-value-annotations-1.6.5.jar
deleted file mode 100644
index f68a013..0000000
--- a/lib/auto-value-annotations-1.6.5.jar
+++ /dev/null
Binary files differ
diff --git a/lib/auto-value-annotations-1.6.5.jar.asc b/lib/auto-value-annotations-1.6.5.jar.asc
deleted file mode 100644
index 1356995..0000000
--- a/lib/auto-value-annotations-1.6.5.jar.asc
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Comment: GPGTools - https://gpgtools.org
-
-iQEzBAABCgAdFiEEx75bzJ/sFVGM/aiCsPNxD6ZJAOcFAlyuMdQACgkQsPNxD6ZJ
-AOeeQQf/cRfXuh8RCDR5WWAHPXpK9JzA5OEEvtXl13uSqpcU+f2/APNOmG9tJz2B
-53bp6d18knaoSAWtC1Hl2kM8eZPYNlpB+MC8VJ+/JAZMf2arLMKGuvii9eYmGrvJ
-kXfRHqWgZQMQIKrd2ne/PMgnmixLPSF6HtyFh2JN/LbjR7ipQR3VAJe89QGmIFFf
-njSptIgKuDauQrjq//yXpWRyhUNheAH42y3aIaUvydcSOLsGIqQfTJLOe3sSMxlU
-d0fJWP47uW04y2j6kXv4SYKXGnBrv2M+c/6YRriPv69tSBc+2DY6SpMZsYdV9Car
-pDM+7m5lxCN8mI/KRRNcXaSR9GLJ2A==
-=ey6m
------END PGP SIGNATURE-----
diff --git a/lib/auto-value-annotations-1.6.5.jar.sha1 b/lib/auto-value-annotations-1.6.5.jar.sha1
deleted file mode 100644
index 858c96e..0000000
--- a/lib/auto-value-annotations-1.6.5.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c3dad10377f0e2242c9a4b88e9704eaf79103679
\ No newline at end of file
diff --git a/lib/google-java-format-0.1-20151017.042846-2.jar b/lib/google-java-format-0.1-20151017.042846-2.jar
new file mode 100644
index 0000000..964760f
--- /dev/null
+++ b/lib/google-java-format-0.1-20151017.042846-2.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/google-java-format-0.1-20151017.042846-2.jar.txt
similarity index 100%
copy from lib/NOTICE
copy to lib/google-java-format-0.1-20151017.042846-2.jar.txt
diff --git a/lib/google-java-format-1.7-all-deps.jar b/lib/google-java-format-1.7-all-deps.jar
deleted file mode 100644
index e2d40de..0000000
--- a/lib/google-java-format-1.7-all-deps.jar
+++ /dev/null
Binary files differ
diff --git a/lib/google-java-format-1.7-all-deps.jar.asc b/lib/google-java-format-1.7-all-deps.jar.asc
deleted file mode 100644
index 73ae0e2..0000000
--- a/lib/google-java-format-1.7-all-deps.jar.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEE53QXrBlBYKP6vQSWmiWcfuY2xe0FAlw2hwoACgkQmiWcfuY2
-xe22Ww//YIHLWoQApuSmLdq4A1fcNOYbSpm6J9I2J1i2VoK84XSXP1XJTWsoYNbx
-Y3Xx6I8p28AxH7LOWcdtds9enbF06blzz+1CxuSxvN32M7DDursiihsUYU9wmZVU
-7V1ZYBtaYTYYw8C5U+UchcIVJrHdG9KrAiBcn1s76gigNAtCYV/1PyryupS1wcDZ
-bdj48mI6adcnIpV+9D9W4rLuXw2Hg+ewktXTj3HYqkg+5Nvc/zP9ueBvqEsyh5Iz
-3+69egblhuN7gRaEWarlYfJ2n/kF9T/UMAkQrWD8+9cOgUcgTHkNADNOLpmDH6t7
-OYvZhgwQT920ZJgGP8e3DGyvMxBMxlr19ciTT19HL5qglyhFm/SeHvFdpaHkIjb9
-CmASWrlkALdEv2gPx+m79EJifyK5tYtViZgLhfjwYkS/opw5TfJX0+Ngh9ehgune
-c6TgEIzRQAEQ/9QoVk2crGT/lhXnJI3Zid7cSP2/fRdui91KaKGi9qFvXyJf7XKI
-vH0De+e3yZN/GXLYyQSUzmdQU8HMF9iuc81CT1ANgU+e9HU5k9FWSPHrA3gN7CKt
-/a3qIsIBpcdKe9zcPxSoEqRzVNept4IhszgiIVxZPNrPShzCRbS1sGURoOTbSFSP
-+aKWNFoswX/RANGQVajOyfF5mJ3lB4N0u2eI0HIR3NzNx0HN+2Q=
-=+/96
------END PGP SIGNATURE-----
diff --git a/lib/google-java-format-1.7-all-deps.jar.sha1 b/lib/google-java-format-1.7-all-deps.jar.sha1
deleted file mode 100644
index b247a7c..0000000
--- a/lib/google-java-format-1.7-all-deps.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b6d34a51e579b08db7c624505bdf9af4397f1702
\ No newline at end of file
diff --git a/lib/google-java-format-1.7-sources.jar b/lib/google-java-format-1.7-sources.jar
deleted file mode 100644
index 70fca1b..0000000
--- a/lib/google-java-format-1.7-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/google-java-format-1.7-sources.jar.asc b/lib/google-java-format-1.7-sources.jar.asc
deleted file mode 100644
index 713333c..0000000
--- a/lib/google-java-format-1.7-sources.jar.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEE53QXrBlBYKP6vQSWmiWcfuY2xe0FAlw2hwsACgkQmiWcfuY2
-xe1j6BAAsDY9DTTcjRtrT6AiZchELcJleOdqK3TRdbl193Mtw5eR+BdKqtcLZSmZ
-1EqYNcldOu9wgbZFpFL99xWNAPOt8tTU9hTsZvrRN0e5CwKXrlJl0MeJi/6yYquG
-FerYGZuDMMEza1q9D2TG5erLOjDEWVLjkSs3jw8mSyMvN0OJFhhMrU4sqhlXMGNV
-lDxeYXLXr+QtIi0tXAUQ5XSwtR7eukSevA7n3zQJKfYMlFbG82lMGJccfazJpdPf
-cJLAGY9/q3RVZx5vk00kz3sDmL+rMU01Lh+CHwT9D8ASRfzjkssHuKaMYBysuh7s
-YZ6X3Txvtkzf3fJjYl5jID3jEui82iR5jv5ncZFZFCsZsTRM0sLAP5/KeX128dHM
-fJzVH4GIUvOqt9aIDKQ+3aNsARsIH2Z2AHymUxVZoP33V9HoC8x0ghxM0xohvkh5
-L+VgUOEjekOneqWD1QEF+HD7S3hpy36+g37PYGcQRRaCIDn00Se+UbJ9RZrUVdvu
-JgmVXcpagrLmcSnkG265zdDW9Vu7vjAKhxjLXmbE0aowzdo/HZ+u3R2hpZbOyv33
-NmakhTwaUtQtDm34GVPqoypnu85va27vxVDQgTsk3im9M1l/UP65NidPuuSk7iOI
-UECD7wc6Ddh80jmDlXdlxSNG+zzGp95gS5UVoDXgwNEok7UgrY4=
-=zj6k
------END PGP SIGNATURE-----
diff --git a/lib/google-java-format-1.7-sources.jar.sha1 b/lib/google-java-format-1.7-sources.jar.sha1
deleted file mode 100644
index 31d6337..0000000
--- a/lib/google-java-format-1.7-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-dbb14f20004dfaf01a5ce9f5e75c5993f18cc0a5
\ No newline at end of file
diff --git a/lib/google-java-format-1.7.jar b/lib/google-java-format-1.7.jar
deleted file mode 100644
index 953541c..0000000
--- a/lib/google-java-format-1.7.jar
+++ /dev/null
Binary files differ
diff --git a/lib/google-java-format-1.7.jar.asc b/lib/google-java-format-1.7.jar.asc
deleted file mode 100644
index 3642d69..0000000
--- a/lib/google-java-format-1.7.jar.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEE53QXrBlBYKP6vQSWmiWcfuY2xe0FAlw2hwkACgkQmiWcfuY2
-xe1uIhAAt9sWjStHkfHmWNFd5exYsjBmN0eObgOU5A386j5Q5P4hZjFDYsDvKlVo
-DWZKI2A9ZvpisuI083DwGJCXvbtD1WICh5Xx1B2tK2oCgl5bYiU88LCw5jS9F2IZ
-thPFhFDMIw4tQZp2J4o+itO7gtoUMfN5J9Y7ZcOWG60F3ouGc6vd8PnMk/CfxNZ0
-Zy21dkBzJVJsNghUWsHfP6WS2ySVBNQaarY+/4IuIrBVqRNZBhD+qEtZRG3mwc4X
-ydd4hCvoAQ7lysrdZEMDRx0qLQoqEWyfNFX7b8X/Oi6Ape765mD3Ss1WFgsjLqo+
-kt4Ge09f4QOCtMP95M8AnnHGjpVuibC0tb2E7qXfcrMWf+EX8ksFJKwaXZQfG4lv
-7kxZDTeeDdU6SUakiwfkEKN6s4v0MrGi8TM+776gLihcD/tx09555h+EwXrbp3IE
-1SWJCiYCuaqe1UXNEsZGYKv72GkPSEjY813Tn3endvGXX+QrLCU6DrLRyy1IWFKJ
-Yu6THeT0Z+M6h+oTO0ug2gJ6Ur7apQC4JBIi12XE+QhwuTuV0byiUArmO+3elLH4
-Nd9O0yFhKClaJ+ye+X+XLYkIjh+IJGFmbUahvCFuMMKuwbFRHwn5pw0DOJvE7qjg
-dBZhwjzKN8RHzik5nFwzhBBIzj3UglacGkUPFv7JW1TqcY2X6kE=
-=VIxo
------END PGP SIGNATURE-----
diff --git a/lib/google-java-format-1.7.jar.sha1 b/lib/google-java-format-1.7.jar.sha1
deleted file mode 100644
index d0a76c2..0000000
--- a/lib/google-java-format-1.7.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-97cb6afc835d65682edc248e19170a8e4ecfe4c4
\ No newline at end of file
diff --git a/lib/javax-inject-src.jar b/lib/javax-inject-src.jar
new file mode 100644
index 0000000..a8a5aa7
--- /dev/null
+++ b/lib/javax-inject-src.jar
Binary files differ
diff --git a/lib/javax-inject.jar b/lib/javax-inject.jar
new file mode 100644
index 0000000..4c86c52
--- /dev/null
+++ b/lib/javax-inject.jar
Binary files differ
diff --git a/lib/NOTICE b/lib/javax-inject.jar.txt
similarity index 100%
copy from lib/NOTICE
copy to lib/javax-inject.jar.txt
diff --git a/lib/javax.inject-1-sources.jar b/lib/javax.inject-1-sources.jar
deleted file mode 100644
index 0c98053..0000000
--- a/lib/javax.inject-1-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/javax.inject-1-sources.jar.sha1 b/lib/javax.inject-1-sources.jar.sha1
deleted file mode 100644
index b69cdf0..0000000
--- a/lib/javax.inject-1-sources.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-a00123f261762a7c5e0ec916a2c7c8298d29c400  /home/maven/repository-staging/to-ibiblio/maven2/javax/inject/javax.inject/1/javax.inject-1-sources.jar
diff --git a/lib/javax.inject-1.jar b/lib/javax.inject-1.jar
deleted file mode 100644
index b2a9d0b..0000000
--- a/lib/javax.inject-1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/javax.inject-1.jar.sha1 b/lib/javax.inject-1.jar.sha1
deleted file mode 100644
index 41e75ef..0000000
--- a/lib/javax.inject-1.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6975da39a7040257bd51d21a231b76c915872d38  /home/maven/repository-staging/to-ibiblio/maven2/javax/inject/javax.inject/1/javax.inject-1.jar
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fcdfe0c
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2012 Square, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <groupId>com.google.dagger</groupId>
+  <artifactId>dagger-parent</artifactId>
+  <packaging>pom</packaging>
+  <version>2.1-SNAPSHOT</version>
+  <name>Dagger (Parent)</name>
+  <description>A fast dependency injector for Android and Java.</description>
+  <url>https://github.com/square/dagger</url>
+
+  <modules>
+    <module>compiler</module>
+    <module>core</module>
+    <!-- examples are handled in a default profile (see below) -->
+    <module>producers</module>
+  </modules>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+    <!-- Compilation -->
+    <java.version>1.7</java.version>
+    <javax.inject.version>1</javax.inject.version>
+    <javax.annotation.version>2.0.1</javax.annotation.version>
+    <javawriter.version>2.5.0</javawriter.version>
+    <auto.common.version>1.0-SNAPSHOT</auto.common.version>
+    <auto.factory.version>1.0-beta3</auto.factory.version>
+    <auto.service.version>1.0-rc2</auto.service.version>
+    <auto.value.version>1.0</auto.value.version>
+    <guava.version>18.0</guava.version>
+    <google.java.format.version>0.1-SNAPSHOT</google.java.format.version>
+
+    <!-- Test Dependencies -->
+    <compile-testing.version>1.0-SNAPSHOT</compile-testing.version>
+    <junit.version>4.11</junit.version>
+    <mockito.version>1.9.5</mockito.version>
+    <truth.version>0.26</truth.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/dagger/</url>
+    <connection>scm:git:git://github.com/google/dagger.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/dagger.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub Issues</system>
+    <url>http://github.com/google/dagger/issues</url>
+  </issueManagement>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+
+  <organization>
+    <name>Google, Inc.</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>javax.inject</groupId>
+        <artifactId>javax.inject</artifactId>
+        <version>${javax.inject.version}</version>
+      </dependency>
+       <dependency>
+        <groupId>javax.inject</groupId>
+        <artifactId>javax.inject-tck</artifactId>
+        <version>${javax.inject.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.code.findbugs</groupId>
+        <artifactId>jsr305</artifactId>
+        <version>${javax.annotation.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup</groupId>
+        <artifactId>javawriter</artifactId>
+        <version>${javawriter.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava-testlib</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.googlejavaformat</groupId>
+        <artifactId>google-java-format</artifactId>
+        <version>${google.java.format.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.auto</groupId>
+        <artifactId>auto-common</artifactId>
+        <version>${auto.common.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.auto.service</groupId>
+        <artifactId>auto-service</artifactId>
+        <version>${auto.service.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.auto.value</groupId>
+        <artifactId>auto-value</artifactId>
+        <version>${auto.value.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>${junit.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.testing.compile</groupId>
+        <artifactId>compile-testing</artifactId>
+        <version>${compile-testing.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>${mockito.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.truth</groupId>
+        <artifactId>truth</artifactId>
+        <version>${truth.version}</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-invoker-plugin</artifactId>
+          <version>1.7</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>2.5</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>${java.version}</source>
+          <target>${java.version}</target>
+          <compilerArgument>-Xlint:all</compilerArgument>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-release-plugin</artifactId>
+        <version>2.3.2</version><!--$NO-MVN-MAN-VER$-->
+        <configuration>
+          <autoVersionSubmodules>true</autoVersionSubmodules>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <doctitle>Dagger Dependency Injection ${project.version} API</doctitle>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>2.10</version>
+        <configuration>
+          <failsOnError>false</failsOnError>
+          <consoleOutput>true</consoleOutput>
+          <configLocation>checkstyle.xml</configLocation>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>checkstyle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+    A profile which when switched off excludes example modules.  By default the profile
+    is on and invokes examples.  However, when processing javadocs, it is switched off
+    omitting the example code from the javadoc.
+  -->
+  <profiles>
+    <profile>
+      <id>examples</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <modules>
+        <module>core</module>
+        <module>compiler</module>
+        <module>examples</module>
+        <module>producers</module>
+      </modules>
+    </profile>
+  </profiles>
+</project>
diff --git a/producers/pom.xml b/producers/pom.xml
new file mode 100644
index 0000000..edaeca4
--- /dev/null
+++ b/producers/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2014 Google, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.dagger</groupId>
+    <artifactId>dagger-parent</artifactId>
+    <version>2.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>dagger-producers</artifactId>
+  <name>Dagger Production Graphs</name>
+  <description>
+    An asynchronous dependency injection system that extends JSR-330.
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>dagger</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/producers/src/main/java/dagger/producers/Produced.java b/producers/src/main/java/dagger/producers/Produced.java
new file mode 100644
index 0000000..db5c133
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/Produced.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.producers;
+
+import com.google.common.base.Objects;
+import dagger.internal.Beta;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * An interface that represents the result of a {@linkplain Producer production} of type {@code T},
+ * or an exception that was thrown during that production. For any type {@code T} that can be
+ * injected, you can also inject {@code Produced<T>}, which enables handling of any exceptions that
+ * were thrown during the production of {@code T}.
+ *
+ * <p>For example: <pre><code>
+ *   {@literal @}Produces Html getResponse(
+ *       UserInfo criticalInfo, {@literal Produced<ExtraInfo>} noncriticalInfo) {
+ *     try {
+ *       return new Html(criticalInfo, noncriticalInfo.get());
+ *     } catch (ExecutionException e) {
+ *       logger.warning(e, "Noncritical info");
+ *       return new Html(criticalInfo);
+ *     }
+ *   }
+ * </code></pre>
+ *
+ * @author Jesse Beder
+ */
+@Beta
+public abstract class Produced<T> {
+  /**
+   * Returns the result of a production.
+   *
+   * @throws ExecutionException if the production threw an exception
+   */
+  public abstract T get() throws ExecutionException;
+
+  /**
+   * Two {@code Produced} objects compare equal if both are successful with equal values, or both
+   * are failed with equal exceptions.
+   */
+  @Override
+  public abstract boolean equals(Object o);
+
+  /** Returns an appropriate hash code to match {@link #equals). */
+  @Override
+  public abstract int hashCode();
+
+  /** Returns a successful {@code Produced}, whose {@link #get} will return the given value. */
+  public static <T> Produced<T> successful(@Nullable T value) {
+    return new Successful<T>(value);
+  }
+
+  /**
+   * Returns a failed {@code Produced}, whose {@link #get} will throw an
+   * {@code ExecutionException} with the given cause.
+   */
+  public static <T> Produced<T> failed(Throwable throwable) {
+    return new Failed<T>(checkNotNull(throwable));
+  }
+
+  private static final class Successful<T> extends Produced<T> {
+    @Nullable private final T value;
+
+    private Successful(@Nullable T value) {
+      this.value = value;
+    }
+
+    @Override public T get() {
+      return value;
+    }
+
+    @Override public boolean equals(Object o) {
+      if (o == this) {
+        return true;
+      } else if (o instanceof Successful) {
+        Successful<?> that = (Successful<?>) o;
+        return Objects.equal(this.value, that.value);
+      } else {
+        return false;
+      }
+    }
+
+    @Override public int hashCode() {
+      return value == null ? 0 : value.hashCode();
+    }
+  }
+
+  private static final class Failed<T> extends Produced<T> {
+    private final Throwable throwable;
+
+    private Failed(Throwable throwable) {
+      this.throwable = checkNotNull(throwable);
+    }
+
+    @Override public T get() throws ExecutionException {
+      throw new ExecutionException(throwable);
+    }
+
+    @Override public boolean equals(Object o) {
+      if (o == this) {
+        return true;
+      } else if (o instanceof Failed) {
+        Failed<?> that = (Failed<?>) o;
+        return this.throwable.equals(that.throwable);
+      } else {
+        return false;
+      }
+    }
+
+    @Override public int hashCode() {
+      return throwable.hashCode();
+    }
+  }
+
+  private Produced() {}
+}
diff --git a/producers/src/main/java/dagger/producers/Producer.java b/producers/src/main/java/dagger/producers/Producer.java
new file mode 100644
index 0000000..eb159bb
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/Producer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.producers;
+
+import dagger.internal.Beta;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * An interface that represents the production of a type {@code T}. You can also inject
+ * {@code Producer<T>} instead of {@code T}, which will delay the execution of any code that
+ * produces the {@code T} until {@link #get} is called.
+ *
+ * <p>For example, you might inject {@code Producer} to lazily choose between several different
+ * implementations of some type: <pre><code>
+ *   {@literal @Produces ListenableFuture<Heater>} getHeater(
+ *       HeaterFlag flag,
+ *       {@literal @Electric Producer<Heater>} electricHeater,
+ *       {@literal @Gas Producer<Heater>} gasHeater) {
+ *     return flag.useElectricHeater() ? electricHeater.get() : gasHeater.get();
+ *   }
+ * </code></pre>
+ *
+ * <p>Here is a complete example that demonstrates how calling {@code get()} will cause each
+ * method to be executed: <pre><code>
+ *
+ *   {@literal @}ProducerModule
+ *   final class MyModule {
+ *     {@literal @Produces ListenableFuture<A>} a() {
+ *       System.out.println("a");
+ *       return Futures.immediateFuture(new A());
+ *     }
+ *
+ *     {@literal @Produces ListenableFuture<B>} b(A a) {
+ *       System.out.println("b");
+ *       return Futures.immediateFuture(new B(a));
+ *     }
+ *
+ *     {@literal @Produces ListenableFuture<C>} c(B b) {
+ *       System.out.println("c");
+ *       return Futures.immediateFuture(new C(b));
+ *     }
+ *
+ *     {@literal @Produces @Delayed ListenableFuture<C>} delayedC(A a, {@literal Producer<C>} c) {
+ *       System.out.println("delayed c");
+ *       return c.get();
+ *     }
+ *   }
+ *
+ *   {@literal @}ProductionComponent(modules = MyModule.class)
+ *   interface MyComponent {
+ *     {@literal @Delayed ListenableFuture<C>} delayedC();
+ *   }
+ * </code></pre>
+ * Suppose we instantiate the generated implementation of this component and call
+ * {@code delayedC()}: <pre><code>
+ *   MyComponent component = DaggerMyComponent
+ *       .builder()
+ *       .executor(MoreExecutors.directExecutor())
+ *       .build();
+ *   System.out.println("Constructed component");
+ *   {@literal ListenableFuture<C>} cFuture = component.delayedC();
+ *   System.out.println("Retrieved future");
+ *   C c = cFuture.get();
+ *   System.out.println("Retrieved c");
+ * </code></pre>
+ * Here, we're using {@code MoreExecutors.directExecutor} in order to illustrate how each call
+ * directly causes code to execute. The above code will print: <pre><code>
+ *   Constructed component
+ *   a
+ *   delayed c
+ *   b
+ *   c
+ *   Retrieved future
+ *   Retrieved c
+ * </code></pre>
+ *
+ * @author Jesse Beder
+ */
+@Beta
+public interface Producer<T> {
+  /**
+   * Returns a future representing a running task that produces a value. Calling this method will
+   * trigger the submission of this task to the executor, if it has not already been triggered. In
+   * order to trigger this task's submission, the transitive dependencies required to produce the
+   * {@code T} will be submitted to the executor, as their dependencies become available.
+   *
+   * <p>If the key is bound to a {@link Produces} method, then calling this method multiple times
+   * will return the same future.
+   */
+  ListenableFuture<T> get();
+}
diff --git a/producers/src/main/java/dagger/producers/ProducerModule.java b/producers/src/main/java/dagger/producers/ProducerModule.java
new file mode 100644
index 0000000..714e3fa
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/ProducerModule.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.producers;
+
+import dagger.Module;
+import dagger.internal.Beta;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * Annotates a class that contributes {@link Produces} bindings to the production component.
+ *
+ * @author Jesse Beder
+ */
+@Documented
+@Target(TYPE)
+@Beta
+public @interface ProducerModule {
+  /**
+   * Additional {@code @ProducerModule}- or {@link Module}-annotated classes from which this module
+   * is composed. The de-duplicated contributions of the modules in {@code includes}, and of their
+   * inclusions recursively, are all contributed to the object graph.
+   */
+  Class<?>[] includes() default {};
+}
diff --git a/producers/src/main/java/dagger/producers/Produces.java b/producers/src/main/java/dagger/producers/Produces.java
new file mode 100644
index 0000000..1b57bc3
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/Produces.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.producers;
+
+import dagger.internal.Beta;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/**
+ * Annotates methods of a producer module to create a production binding. If the method returns
+ * a {@link ListenableFuture}, then the parameter type of the future is bound to the value that the
+ * future provides; otherwise, the return type is bound to the returned value. The production
+ * component will pass dependencies to the method as parameters.
+ *
+ * @author Jesse Beder
+ */
+@Documented
+@Target(METHOD)
+@Beta
+public @interface Produces {
+  /** The type of binding into which the return type of the annotated method contributes. */
+  enum Type {
+    /**
+     * The method is the only one which can produce the value for the specified type. This is the
+     * default behavior.
+     */
+    UNIQUE,
+
+    /**
+     * The method's resulting type forms the generic type argument of a {@code Set<T>}, and the
+     * returned value or future is contributed to the set. The {@code Set<T>} produced from the
+     * accumulation of values will be immutable.
+     */
+    SET,
+
+    /**
+     * Like {@link #SET}, except the method's return type is either {@code Set<T>} or
+     * {@code Set<ListenableFuture<T>>}, where any values are contributed to the set. An example use
+     * is to provide a default empty set binding, which is otherwise not possible using
+     * {@link #SET}.
+     */
+    SET_VALUES,
+
+    /**
+     * The method's return type forms the type argument for the value of a
+     * {@code Map<K, Producer<V>>}, and the combination of the annotated key and the returned value
+     * is contributed to the map as a key/value pair. The {@code Map<K, Producer<V>>} produced from
+     * the accumulation of values will be immutable.
+     */
+    MAP;
+  }
+
+  Type type() default Type.UNIQUE;
+}
diff --git a/producers/src/main/java/dagger/producers/ProductionComponent.java b/producers/src/main/java/dagger/producers/ProductionComponent.java
new file mode 100644
index 0000000..8ccdb44
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/ProductionComponent.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.producers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.Module;
+import dagger.Provides;
+import dagger.internal.Beta;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import javax.inject.Inject;
+import javax.inject.Qualifier;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * Annotates an interface or abstract class for which a fully-formed, dependency-injected
+ * implementation is to be generated from a set of {@linkplain #modules}. The generated class will
+ * have the name of the type annotated with {@code @ProductionComponent} prepended with
+ * {@code Dagger}.  For example, {@code @ProductionComponent interface MyComponent {...}} will
+ * produce an implementation named {@code DaggerMyComponent}.
+ *
+ * <p>Each {@link Produces} method that contributes to the component will be called at most once per
+ * component instance, no matter how many times that binding is used as a dependency.
+ * TODO(user): Decide on how scope works for producers.
+ *
+ * <h2>Component methods</h2>
+ *
+ * <p>Every type annotated with {@code @ProductionComponent} must contain at least one abstract
+ * component method. Component methods must represent {@linkplain Producer production}.
+ *
+ * Production methods have no arguments and return either a {@link ListenableFuture} or
+ * {@link Producer} of a type that is {@link Inject injected}, {@link Provides provided}, or
+ * {@link Produces produced}. Each may have a {@link Qualifier} annotation as well. The following
+ * are all valid production method declarations: <pre><code>
+ *   ListenableFuture<SomeType> getSomeType();
+ *   {@literal Producer<Set<SomeType>>} getSomeTypes();
+ *   {@literal @Response ListenableFuture<Html>} getResponse();
+ * </code></pre>
+ *
+ * <h2>Exceptions</h2>
+ *
+ * <p>When a producer throws an exception, the exception will be propagated to its downstream
+ * producers in the following way: if the downstream producer injects a type {@code T}, then that
+ * downstream producer will be skipped, and the exception propagated to its downstream producers;
+ * and if the downstream producer injects a {@code Produced<T>}, then the downstream producer will
+ * be run with the exception stored in the {@code Produced<T>}.
+ *
+ * <p>If a non-execution exception is thrown (e.g., an {@code InterruptedException} or
+ * {@code CancellationException}), then exception is handled as in
+ * {@link com.google.common.util.concurrent.Futures#transform}.
+ * <!-- TODO(beder): Explain this more thoroughly, and update the javadocs of those utilities. -->
+ *
+ * @author Jesse Beder
+ */
+@Documented
+@Target(TYPE)
+@Beta
+public @interface ProductionComponent {
+  /**
+   * A list of classes annotated with {@link Module} or {@link ProducerModule} whose bindings are
+   * used to generate the component implementation.
+   */
+  Class<?>[] modules() default {};
+
+  /**
+   * A list of types that are to be used as component dependencies.
+   */
+  Class<?>[] dependencies() default {};
+
+  /**
+   * A builder for a component. Components may have a single nested static abstract class or
+   * interface annotated with {@code @ProductionComponent.Builder}. If they do, then the component's
+   * generated builder will match the API in the type.  Builders must follow some rules:
+   * <ul>
+   * <li> A single abstract method with no arguments must exist, and must return the component.
+   *      (This is typically the {@code build()} method.)
+   * <li> All other abstract methods must take a single argument and must return void,
+   *      the builder type, or a supertype of the builder.
+   * <li> There <b>must</b> be an abstract method whose parameter is
+   *      {@link java.util.concurrent.Executor}.
+   * <li> Each component dependency <b>must</b> have an abstract setter method.
+   * <li> Each module dependency that Dagger can't instantiate itself (i.e., the module
+   *      doesn't have a visible no-args constructor) <b>must</b> have an abstract setter method.
+   *      Other module dependencies (ones that Dagger can instantiate) are allowed, but not
+   *      required.
+   * <li> Non-abstract methods are allowed, but ignored as far as validation and builder generation
+   *      are concerned.
+   * </ul>
+   *
+   * For example, this could be a valid {@code ProductionComponent} with a builder: <pre><code>
+   * {@literal @}ProductionComponent(modules = {BackendModule.class, FrontendModule.class})
+   * interface MyComponent {
+   *   {@literal ListenableFuture<MyWidget>} myWidget();
+   *
+   *   {@literal @}ProductionComponent.Builder
+   *   interface Builder {
+   *     MyComponent build();
+   *     Builder executor(Executor executor);
+   *     Builder backendModule(BackendModule bm);
+   *     Builder frontendModule(FrontendModule fm);
+   *   }
+   * }</code></pre>
+   */
+  @Target(TYPE)
+  @Documented
+  @interface Builder {}
+}
diff --git a/producers/src/main/java/dagger/producers/internal/AbstractProducer.java b/producers/src/main/java/dagger/producers/internal/AbstractProducer.java
new file mode 100644
index 0000000..f7e8ec0
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/internal/AbstractProducer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import dagger.producers.monitoring.internal.Monitors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nullable;
+import javax.inject.Provider;
+
+/**
+ * An abstract {@link Producer} implementation that memoizes the result of its compute method.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+public abstract class AbstractProducer<T> implements Producer<T> {
+  private final Provider<ProductionComponentMonitor> monitorProvider;
+  @Nullable private final ProducerToken token;
+  private volatile ListenableFuture<T> instance = null;
+
+  protected AbstractProducer() {
+    this(Monitors.noOpProductionComponentMonitorProvider(), null);
+  }
+
+  protected AbstractProducer(
+      Provider<ProductionComponentMonitor> monitorProvider, @Nullable ProducerToken token) {
+    this.monitorProvider = checkNotNull(monitorProvider);
+    this.token = token;
+  }
+
+  /** Computes this producer's future, which is then cached in {@link #get}. */
+  protected abstract ListenableFuture<T> compute(ProducerMonitor monitor);
+
+  @Override
+  public final ListenableFuture<T> get() {
+    // double-check idiom from EJ2: Item 71
+    ListenableFuture<T> result = instance;
+    if (result == null) {
+      synchronized (this) {
+        result = instance;
+        if (result == null) {
+          ProducerMonitor monitor = monitorProvider.get().producerMonitorFor(token);
+          instance = result = compute(monitor);
+          if (result == null) {
+            throw new NullPointerException("compute returned null");
+          }
+          monitor.addCallbackTo(result);
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/internal/Producers.java b/producers/src/main/java/dagger/producers/internal/Producers.java
new file mode 100644
index 0000000..7052c35
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/internal/Producers.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.FutureFallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import java.util.Set;
+import javax.inject.Provider;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Utility methods for use in generated producer code.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+public final class Producers {
+  /**
+   * Returns a future of {@link Produced} that represents the completion (either success or failure)
+   * of the given future. If the input future succeeds, then the resulting future also succeeds with
+   * a successful {@code Produced}; if the input future fails, then the resulting future succeeds
+   * with a failing {@code Produced}.
+   *
+   * <p>Cancelling the resulting future will propagate the cancellation to the input future; but
+   * cancelling the input future will trigger the resulting future to succeed with a failing
+   * {@code Produced}.
+   */
+  // TODO(user): Document what happens with an InterruptedException after you figure out how to
+  // trigger one in a test.
+  public static <T> ListenableFuture<Produced<T>> createFutureProduced(ListenableFuture<T> future) {
+    // TODO(dpb): Switch to Futures.catchAsync once guava_jdk5 gets to v19.
+    return Futures.withFallback(
+        Futures.transform(
+            future,
+            new Function<T, Produced<T>>() {
+              @Override
+              public Produced<T> apply(final T value) {
+                return Produced.successful(value);
+              }
+            }),
+        Producers.<T>futureFallbackForProduced());
+
+  }
+
+  private static final FutureFallback<Produced<Object>> FUTURE_FALLBACK_FOR_PRODUCED =
+      new FutureFallback<Produced<Object>>() {
+    @Override public ListenableFuture<Produced<Object>> create(final Throwable t) {
+      Produced<Object> produced = Produced.failed(t);
+      return Futures.immediateFuture(produced);
+    }
+  };
+
+  @SuppressWarnings({"unchecked", "rawtypes"})  // bivariant implementation
+  private static <T> FutureFallback<Produced<T>> futureFallbackForProduced() {
+    return (FutureFallback) FUTURE_FALLBACK_FOR_PRODUCED;
+  }
+
+  /**
+   * Returns a future of a {@code Set} that contains a single element: the result of the input
+   * future.
+   */
+  public static <T> ListenableFuture<Set<T>> createFutureSingletonSet(ListenableFuture<T> future) {
+    return Futures.transform(future, new Function<T, Set<T>>() {
+      @Override public Set<T> apply(T value) {
+        return ImmutableSet.of(value);
+      }
+    });
+  }
+
+  /**
+   * Returns a producer that immediately executes the binding logic for the given provider every
+   * time it is called.
+   */
+  public static <T> Producer<T> producerFromProvider(final Provider<T> provider) {
+    checkNotNull(provider);
+    return new AbstractProducer<T>() {
+      @Override
+      protected ListenableFuture<T> compute(ProducerMonitor unusedMonitor) {
+        return Futures.immediateFuture(provider.get());
+      }
+    };
+  }
+
+  /** Returns a producer that succeeds with the given value. */
+  public static <T> Producer<T> immediateProducer(final T value) {
+    return new Producer<T>() {
+      @Override
+      public ListenableFuture<T> get() {
+        return Futures.immediateFuture(value);
+      }
+    };
+  }
+
+  /** Returns a producer that fails with the given exception. */
+  public static <T> Producer<T> immediateFailedProducer(final Throwable throwable) {
+    return new Producer<T>() {
+      @Override
+      public ListenableFuture<T> get() {
+        return Futures.immediateFailedFuture(throwable);
+      }
+    };
+  }
+
+  private Producers() {}
+}
diff --git a/producers/src/main/java/dagger/producers/internal/SetOfProducedProducer.java b/producers/src/main/java/dagger/producers/internal/SetOfProducedProducer.java
new file mode 100644
index 0000000..e51bcad
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/internal/SetOfProducedProducer.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * A {@link Producer} implementation used to implement {@link Set} bindings. This producer returns a
+ * future {@code Set<Produced<T>>} whose elements are populated by subsequent calls to the delegate
+ * {@link Producer#get} methods.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+public final class SetOfProducedProducer<T> extends AbstractProducer<Set<Produced<T>>> {
+  /**
+   * Returns a new producer that creates {@link Set} futures from the union of the given
+   * {@link Producer} instances.
+   */
+  @SafeVarargs
+  public static <T> Producer<Set<Produced<T>>> create(Producer<Set<T>>... producers) {
+    return new SetOfProducedProducer<T>(ImmutableSet.copyOf(producers));
+  }
+
+  private final ImmutableSet<Producer<Set<T>>> contributingProducers;
+
+  private SetOfProducedProducer(ImmutableSet<Producer<Set<T>>> contributingProducers) {
+    this.contributingProducers = contributingProducers;
+  }
+
+  /**
+   * Returns a future {@link Set} of {@link Produced} values whose iteration order is that of the
+   * elements given by each of the producers, which are invoked in the order given at creation.
+   *
+   * <p>If any of the delegate sets, or any elements therein, are null, then that corresponding
+   * {@code Produced} element will fail with a NullPointerException.
+   *
+   * <p>Canceling this future will attempt to cancel all of the component futures; but if any of the
+   * delegate futures fail or are canceled, this future succeeds, with the appropriate failed
+   * {@link Produced}.
+   *
+   * @throws NullPointerException if any of the delegate producers return null
+   */
+  @Override
+  public ListenableFuture<Set<Produced<T>>> compute(ProducerMonitor unusedMonitor) {
+    List<ListenableFuture<Produced<Set<T>>>> futureProducedSets =
+        new ArrayList<ListenableFuture<Produced<Set<T>>>>(contributingProducers.size());
+    for (Producer<Set<T>> producer : contributingProducers) {
+      ListenableFuture<Set<T>> futureSet = producer.get();
+      if (futureSet == null) {
+        throw new NullPointerException(producer + " returned null");
+      }
+      futureProducedSets.add(Producers.createFutureProduced(futureSet));
+    }
+    return Futures.transform(
+        Futures.allAsList(futureProducedSets),
+        new Function<List<Produced<Set<T>>>, Set<Produced<T>>>() {
+          @Override
+          public Set<Produced<T>> apply(List<Produced<Set<T>>> producedSets) {
+            ImmutableSet.Builder<Produced<T>> builder = ImmutableSet.builder();
+            for (Produced<Set<T>> producedSet : producedSets) {
+              try {
+                Set<T> set = producedSet.get();
+                if (set == null) {
+                  // TODO(beder): This is a vague exception. Can we somehow point to the failing
+                  // producer? See the similar comment in the component writer about null
+                  // provisions.
+                  builder.add(
+                      Produced.<T>failed(
+                          new NullPointerException(
+                              "Cannot contribute a null set into a producer set binding when it's"
+                                  + " injected as Set<Produced<T>>.")));
+                } else {
+                  for (T value : set) {
+                    if (value == null) {
+                      builder.add(
+                          Produced.<T>failed(
+                              new NullPointerException(
+                                  "Cannot contribute a null element into a producer set binding"
+                                      + " when it's injected as Set<Produced<T>>.")));
+                    } else {
+                      builder.add(Produced.successful(value));
+                    }
+                  }
+                }
+              } catch (ExecutionException e) {
+                builder.add(Produced.<T>failed(e.getCause()));
+              }
+            }
+            return builder.build();
+          }
+        });
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/internal/SetProducer.java b/producers/src/main/java/dagger/producers/internal/SetProducer.java
new file mode 100644
index 0000000..5b3c090
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/internal/SetProducer.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A {@link Producer} implementation used to implement {@link Set} bindings. This producer returns
+ * a future {@link Set} whose elements are populated by subsequent calls to the delegate
+ * {@link Producer#get} methods.
+ *
+ * @author Jesse Beder
+ * @since 2.0
+ */
+public final class SetProducer<T> extends AbstractProducer<Set<T>> {
+  /**
+   * Returns a new producer that creates {@link Set} futures from the union of the given
+   * {@link Producer} instances.
+   */
+  @SafeVarargs
+  public static <T> Producer<Set<T>> create(Producer<Set<T>>... producers) {
+    return new SetProducer<T>(ImmutableSet.copyOf(producers));
+  }
+
+  private final Set<Producer<Set<T>>> contributingProducers;
+
+  private SetProducer(Set<Producer<Set<T>>> contributingProducers) {
+    super();
+    this.contributingProducers = contributingProducers;
+  }
+
+  /**
+   * Returns a future {@link Set} whose iteration order is that of the elements given by each of the
+   * producers, which are invoked in the order given at creation.
+   *
+   * <p>If any of the delegate sets, or any elements therein, are null, then this future will fail
+   * with a NullPointerException.
+   *
+   * <p>Canceling this future will attempt to cancel all of the component futures, and if any of the
+   * delegate futures fails or is canceled, this one is, too.
+   *
+   * @throws NullPointerException if any of the delegate producers return null
+   */
+  @Override
+  public ListenableFuture<Set<T>> compute(ProducerMonitor unusedMonitor) {
+    List<ListenableFuture<Set<T>>> futureSets =
+        new ArrayList<ListenableFuture<Set<T>>>(contributingProducers.size());
+    for (Producer<Set<T>> producer : contributingProducers) {
+      ListenableFuture<Set<T>> futureSet = producer.get();
+      if (futureSet == null) {
+        throw new NullPointerException(producer + " returned null");
+      }
+      futureSets.add(futureSet);
+    }
+    return Futures.transform(Futures.allAsList(futureSets), new Function<List<Set<T>>, Set<T>>() {
+      @Override public Set<T> apply(List<Set<T>> sets) {
+        ImmutableSet.Builder<T> builder = ImmutableSet.builder();
+        for (Set<T> set : sets) {
+          builder.addAll(set);
+        }
+        return builder.build();
+      }
+    });
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/ProducerMonitor.java b/producers/src/main/java/dagger/producers/monitoring/ProducerMonitor.java
new file mode 100644
index 0000000..20551c3
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/ProducerMonitor.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.producers.monitoring;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Produces;
+
+/**
+ * A hook for monitoring the execution of individual {@linkplain Produces producer methods}. See
+ * {@link ProductionComponentMonitor} for how to install these monitors.
+ *
+ * <p>The lifecycle of the monitor, under normal conditions, is:
+ * <ul>
+ *   <li>{@link #methodStarting()}
+ *   <li>The method is called
+ *   <li>{@link #methodFinished()}
+ *   <li>If the method returns a value, then:
+ *   <ul>
+ *     <li>{@link #succeeded(Object)} if the method returned normally; or
+ *     <li>{@link #failed(Throwable)} if the method threw an exception.
+ *   </ul>
+ *   <li>If the method returns a future, then:
+ *   <ul>
+ *     <li>{@link #succeeded(Object)} if the method returned normally, and the future succeeded; or
+ *     <li>{@link #failed(Throwable)} if the method threw an exception, or returned normally and the
+ *         future failed.
+ *   </ul>
+ * </ul>
+ *
+ * <p>If any input to the monitored producer fails, {@link #failed(Throwable)} will be called
+ * immediately with the failed input's exception. If more than one input fails, an arbitrary failed
+ * input's exception is used.
+ *
+ * <p>If any of the monitor's methods throw, then the exception will be logged and processing will
+ * continue unaffected.
+ *
+ * @author Jesse Beder
+ */
+public abstract class ProducerMonitor {
+  /**
+   * Called when the producer method is about to start executing.
+   *
+   * <p>When multiple monitors are installed, the order that each monitor will call this method is
+   * unspecified, but will remain consistent throughout the course of the execution of a component.
+   */
+  public void methodStarting() {}
+
+  /**
+   * Called when the producer method has finished executing.
+   *
+   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
+   * calls to {@link #methodStarting()}.
+   */
+  public void methodFinished() {}
+
+  /**
+   * Called when the producer’s future has completed successfully with a value.
+   *
+   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
+   * calls to {@link #methodStarting()}.
+   */
+  public void succeeded(Object o) {}
+
+  /**
+   * Called when the producer's future has failed with an exception.
+   *
+   * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
+   * calls to {@link #methodStarting()}.
+   */
+  public void failed(Throwable t) {}
+
+  /**
+   * Adds this monitor's completion methods as a callback to the future. This is only intended to be
+   * overridden in the framework!
+   */
+  public <T> void addCallbackTo(ListenableFuture<T> future) {
+    Futures.addCallback(
+        future,
+        new FutureCallback<T>() {
+          @Override
+          public void onSuccess(T value) {
+            succeeded(value);
+          }
+
+          @Override
+          public void onFailure(Throwable t) {
+            failed(t);
+          }
+        });
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/ProducerToken.java b/producers/src/main/java/dagger/producers/monitoring/ProducerToken.java
new file mode 100644
index 0000000..5834206
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/ProducerToken.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.producers.monitoring;
+
+import dagger.producers.Produces;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/** A token that represents an individual {@linkplain Produces producer method}. */
+public final class ProducerToken {
+  private final Class<?> classToken;
+
+  private ProducerToken(Class<?> classToken) {
+    this.classToken = classToken;
+  }
+
+  /**
+   * Creates a token for a class token that represents the generated factory for a producer method.
+   *
+   * <p><b>Do not use this!</b> This is intended to be called by generated code only, and its
+   * signature may change at any time.
+   */
+  public static ProducerToken create(Class<?> classToken) {
+    return new ProducerToken(checkNotNull(classToken));
+  }
+
+  /** Two tokens are equal if they represent the same method. */
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    } else if (o instanceof ProducerToken) {
+      ProducerToken that = (ProducerToken) o;
+      return this.classToken.equals(that.classToken);
+    } else {
+      return false;
+    }
+  }
+
+  /** Returns an appropriate hash code to match {@link #equals). */
+  @Override
+  public int hashCode() {
+    return classToken.hashCode();
+  }
+
+  /** Returns a representation of the method. */
+  @Override
+  public String toString() {
+    return classToken.toString();
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/ProductionComponentMonitor.java b/producers/src/main/java/dagger/producers/monitoring/ProductionComponentMonitor.java
new file mode 100644
index 0000000..4dc2903
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/ProductionComponentMonitor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.producers.monitoring;
+
+import dagger.producers.Produces;
+import dagger.producers.ProductionComponent;
+
+/**
+ * A hook for monitoring execution of {@linkplain ProductionComponent production components}. To
+ * install a {@code ProductionComponentMonitor}, contribute to a set binding of
+ * {@code ProductionComponentMonitor.Factory}. The factory will be asked to create one monitor for
+ * the component, and the resulting single instance will be used to create individual monitors for
+ * producers.
+ *
+ * <p>For example: <pre><code>
+ *   {@literal @Module}
+ *   final class MyMonitorModule {
+ *     {@literal @Provides(type = SET)} ProductionComponentMonitor.Factory provideMonitorFactory(
+ *         MyProductionComponentMonitor.Factory monitorFactory) {
+ *       return monitorFactory;
+ *     }
+ *   }
+ *
+ *   {@literal @ProductionComponent(modules = {MyMonitorModule.class, MyProducerModule.class})}
+ *   interface MyComponent {
+ *     {@literal ListenableFuture<SomeType>} someType();
+ *   }
+ * </code></pre>
+ *
+ * <p>If any of these methods throw, then the exception will be logged, and the framework will act
+ * as though a no-op monitor was returned.
+ *
+ * @author Jesse Beder
+ */
+public interface ProductionComponentMonitor {
+  /** Returns a monitor for an individual {@linkplain Produces producer method}. */
+  ProducerMonitor producerMonitorFor(ProducerToken token);
+
+  public interface Factory {
+    /** Creates a component-specific monitor when the component is created. */
+    ProductionComponentMonitor create(Object component);
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/internal/MonitorCache.java b/producers/src/main/java/dagger/producers/monitoring/internal/MonitorCache.java
new file mode 100644
index 0000000..2a76c5f
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/internal/MonitorCache.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers.monitoring.internal;
+
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.inject.Provider;
+
+/**
+ * A class that provides a {@link ProductionComponentMonitor} for use in production components.
+ *
+ * <p>This caches the underlying the monitor, since we want a single instance for each component.
+ */
+public final class MonitorCache {
+  private static final Logger logger = Logger.getLogger(MonitorCache.class.getName());
+
+  private volatile ProductionComponentMonitor monitor;
+
+  /**
+   * Returns the underlying monitor. This will only actually compute the monitor the first time it
+   * is called; subsequent calls will simply return the cached value, so the arguments to this
+   * method are ignored. It is expected (though not checked) that this method is called with
+   * equivalent arguments each time (like a {@link dagger.Provides @Provides} method would).
+   */
+  public ProductionComponentMonitor monitor(
+      Provider<?> componentProvider,
+      Provider<Set<ProductionComponentMonitor.Factory>> monitorFactorySetProvider) {
+    ProductionComponentMonitor result = monitor;
+    if (result == null) {
+      synchronized (this) {
+        result = monitor;
+        if (result == null) {
+          try {
+            ProductionComponentMonitor.Factory factory =
+                Monitors.delegatingProductionComponentMonitorFactory(
+                    monitorFactorySetProvider.get());
+            result = monitor = factory.create(componentProvider.get());
+          } catch (RuntimeException e) {
+            logger.log(Level.SEVERE, "RuntimeException while constructing monitor factories.", e);
+            result = monitor = Monitors.noOpProductionComponentMonitor();
+          }
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/internal/Monitors.java b/producers/src/main/java/dagger/producers/monitoring/internal/Monitors.java
new file mode 100644
index 0000000..f27ce37
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/internal/Monitors.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.producers.monitoring.internal;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.inject.Provider;
+
+/**
+ * Utility methods relating to monitoring, for use in generated producers code.
+ *
+ * @author Jesse Beder
+ */
+public final class Monitors {
+  private static final Logger logger = Logger.getLogger(Monitors.class.getName());
+
+  /**
+   * Returns a monitor factory that delegates to the given factories, and ensures that any method
+   * called on this object, even transitively, does not throw a {@link RuntimeException} or return
+   * null.
+   *
+   * <p>If the delegate monitors throw an {@link Error}, then that will escape this monitor
+   * implementation. Errors are treated as unrecoverable conditions, and may cause the entire
+   * component's execution to fail.
+   */
+  public static ProductionComponentMonitor.Factory delegatingProductionComponentMonitorFactory(
+      Collection<? extends ProductionComponentMonitor.Factory> factories) {
+    if (factories.isEmpty()) {
+      return noOpProductionComponentMonitorFactory();
+    } else if (factories.size() == 1) {
+      return new NonThrowingProductionComponentMonitor.Factory(Iterables.getOnlyElement(factories));
+    } else {
+      return new DelegatingProductionComponentMonitor.Factory(factories);
+    }
+  }
+
+  /**
+   * A component monitor that delegates to a single monitor, and catches and logs all exceptions
+   * that the delegate throws.
+   */
+  private static final class NonThrowingProductionComponentMonitor
+      implements ProductionComponentMonitor {
+    private final ProductionComponentMonitor delegate;
+
+    NonThrowingProductionComponentMonitor(ProductionComponentMonitor delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public ProducerMonitor producerMonitorFor(ProducerToken token) {
+      try {
+        ProducerMonitor monitor = delegate.producerMonitorFor(token);
+        return monitor == null ? noOpProducerMonitor() : new NonThrowingProducerMonitor(monitor);
+      } catch (RuntimeException e) {
+        logProducerMonitorForException(e, delegate, token);
+        return noOpProducerMonitor();
+      }
+    }
+
+    static final class Factory implements ProductionComponentMonitor.Factory {
+      private final ProductionComponentMonitor.Factory delegate;
+
+      Factory(ProductionComponentMonitor.Factory delegate) {
+        this.delegate = delegate;
+      }
+
+      @Override
+      public ProductionComponentMonitor create(Object component) {
+        try {
+          ProductionComponentMonitor monitor = delegate.create(component);
+          return monitor == null
+              ? noOpProductionComponentMonitor()
+              : new NonThrowingProductionComponentMonitor(monitor);
+        } catch (RuntimeException e) {
+          logCreateException(e, delegate, component);
+          return noOpProductionComponentMonitor();
+        }
+      }
+    }
+  }
+
+  /**
+   * A producer monitor that delegates to a single monitor, and catches and logs all exceptions
+   * that the delegate throws.
+   */
+  private static final class NonThrowingProducerMonitor extends ProducerMonitor {
+    private final ProducerMonitor delegate;
+
+    NonThrowingProducerMonitor(ProducerMonitor delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public void methodStarting() {
+      try {
+        delegate.methodStarting();
+      } catch (RuntimeException e) {
+        logProducerMonitorMethodException(e, delegate, "methodStarting");
+      }
+    }
+
+    @Override
+    public void methodFinished() {
+      try {
+        delegate.methodFinished();
+      } catch (RuntimeException e) {
+        logProducerMonitorMethodException(e, delegate, "methodFinished");
+      }
+    }
+
+    @Override
+    public void succeeded(Object o) {
+      try {
+        delegate.succeeded(o);
+      } catch (RuntimeException e) {
+        logProducerMonitorArgMethodException(e, delegate, "succeeded", o);
+      }
+    }
+
+    @Override
+    public void failed(Throwable t) {
+      try {
+        delegate.failed(t);
+      } catch (RuntimeException e) {
+        logProducerMonitorArgMethodException(e, delegate, "failed", t);
+      }
+    }
+  }
+
+  /**
+   * A component monitor that delegates to several monitors, and catches and logs all exceptions
+   * that the delegates throw.
+   */
+  private static final class DelegatingProductionComponentMonitor
+      implements ProductionComponentMonitor {
+    private final ImmutableList<ProductionComponentMonitor> delegates;
+
+    DelegatingProductionComponentMonitor(ImmutableList<ProductionComponentMonitor> delegates) {
+      this.delegates = delegates;
+    }
+
+    @Override
+    public ProducerMonitor producerMonitorFor(ProducerToken token) {
+      ImmutableList.Builder<ProducerMonitor> monitorsBuilder = ImmutableList.builder();
+      for (ProductionComponentMonitor delegate : delegates) {
+        try {
+          ProducerMonitor monitor = delegate.producerMonitorFor(token);
+          if (monitor != null) {
+            monitorsBuilder.add(monitor);
+          }
+        } catch (RuntimeException e) {
+          logProducerMonitorForException(e, delegate, token);
+        }
+      }
+      ImmutableList<ProducerMonitor> monitors = monitorsBuilder.build();
+      if (monitors.isEmpty()) {
+        return noOpProducerMonitor();
+      } else if (monitors.size() == 1) {
+        return new NonThrowingProducerMonitor(Iterables.getOnlyElement(monitors));
+      } else {
+        return new DelegatingProducerMonitor(monitors);
+      }
+    }
+
+    static final class Factory implements ProductionComponentMonitor.Factory {
+      private final ImmutableList<? extends ProductionComponentMonitor.Factory> delegates;
+
+      Factory(Iterable<? extends ProductionComponentMonitor.Factory> delegates) {
+        this.delegates = ImmutableList.copyOf(delegates);
+      }
+
+      @Override
+      public ProductionComponentMonitor create(Object component) {
+        ImmutableList.Builder<ProductionComponentMonitor> monitorsBuilder = ImmutableList.builder();
+        for (ProductionComponentMonitor.Factory delegate : delegates) {
+          try {
+            ProductionComponentMonitor monitor = delegate.create(component);
+            if (monitor != null) {
+              monitorsBuilder.add(monitor);
+            }
+          } catch (RuntimeException e) {
+            logCreateException(e, delegate, component);
+          }
+        }
+        ImmutableList<ProductionComponentMonitor> monitors = monitorsBuilder.build();
+        if (monitors.isEmpty()) {
+          return noOpProductionComponentMonitor();
+        } else if (monitors.size() == 1) {
+          return new NonThrowingProductionComponentMonitor(Iterables.getOnlyElement(monitors));
+        } else {
+          return new DelegatingProductionComponentMonitor(monitors);
+        }
+      }
+    }
+  }
+
+  /**
+   * A producer monitor that delegates to several monitors, and catches and logs all exceptions
+   * that the delegates throw.
+   */
+  private static final class DelegatingProducerMonitor extends ProducerMonitor {
+    private final ImmutableList<ProducerMonitor> delegates;
+
+    DelegatingProducerMonitor(ImmutableList<ProducerMonitor> delegates) {
+      this.delegates = delegates;
+    }
+
+    @Override
+    public void methodStarting() {
+      for (ProducerMonitor delegate : delegates) {
+        try {
+          delegate.methodStarting();
+        } catch (RuntimeException e) {
+          logProducerMonitorMethodException(e, delegate, "methodStarting");
+        }
+      }
+    }
+
+    @Override
+    public void methodFinished() {
+      for (ProducerMonitor delegate : delegates.reverse()) {
+        try {
+          delegate.methodFinished();
+        } catch (RuntimeException e) {
+          logProducerMonitorMethodException(e, delegate, "methodFinished");
+        }
+      }
+    }
+
+    @Override
+    public void succeeded(Object o) {
+      for (ProducerMonitor delegate : delegates.reverse()) {
+        try {
+          delegate.succeeded(o);
+        } catch (RuntimeException e) {
+          logProducerMonitorArgMethodException(e, delegate, "succeeded", o);
+        }
+      }
+    }
+
+    @Override
+    public void failed(Throwable t) {
+      for (ProducerMonitor delegate : delegates.reverse()) {
+        try {
+          delegate.failed(t);
+        } catch (RuntimeException e) {
+          logProducerMonitorArgMethodException(e, delegate, "failed", t);
+        }
+      }
+    }
+  }
+
+  /** Returns a monitor factory that returns no-op component monitors. */
+  public static ProductionComponentMonitor.Factory noOpProductionComponentMonitorFactory() {
+    return NO_OP_PRODUCTION_COMPONENT_MONITOR_FACTORY;
+  }
+
+  /** Returns a component monitor that returns no-op producer monitors. */
+  public static ProductionComponentMonitor noOpProductionComponentMonitor() {
+    return NO_OP_PRODUCTION_COMPONENT_MONITOR;
+  }
+
+  /** Returns a producer monitor that does nothing. */
+  public static ProducerMonitor noOpProducerMonitor() {
+    return NO_OP_PRODUCER_MONITOR;
+  }
+
+  /** Returns a provider of a no-op component monitor. */
+  public static Provider<ProductionComponentMonitor> noOpProductionComponentMonitorProvider() {
+    return NO_OP_PRODUCTION_COMPONENT_MONITOR_PROVIDER;
+  }
+
+  private static final ProductionComponentMonitor.Factory
+      NO_OP_PRODUCTION_COMPONENT_MONITOR_FACTORY =
+          new ProductionComponentMonitor.Factory() {
+            @Override
+            public ProductionComponentMonitor create(Object component) {
+              return noOpProductionComponentMonitor();
+            }
+          };
+
+  private static final ProductionComponentMonitor NO_OP_PRODUCTION_COMPONENT_MONITOR =
+      new ProductionComponentMonitor() {
+        @Override
+        public ProducerMonitor producerMonitorFor(ProducerToken token) {
+          return noOpProducerMonitor();
+        }
+      };
+
+  private static final ProducerMonitor NO_OP_PRODUCER_MONITOR =
+      new ProducerMonitor() {
+        @Override
+        public <T> void addCallbackTo(ListenableFuture<T> future) {
+          // overridden to avoid adding a do-nothing callback
+        }
+      };
+
+  private static final Provider<ProductionComponentMonitor>
+      NO_OP_PRODUCTION_COMPONENT_MONITOR_PROVIDER =
+          new Provider() {
+            @Override
+            public ProductionComponentMonitor get() {
+              return noOpProductionComponentMonitor();
+            }
+          };
+
+  private static void logCreateException(
+      RuntimeException e, ProductionComponentMonitor.Factory factory, Object component) {
+    logger.log(
+        Level.SEVERE,
+        "RuntimeException while calling ProductionComponentMonitor.Factory.create on factory "
+            + factory
+            + " with component "
+            + component,
+        e);
+  }
+
+  private static void logProducerMonitorForException(
+      RuntimeException e, ProductionComponentMonitor monitor, ProducerToken token) {
+    logger.log(
+        Level.SEVERE,
+        "RuntimeException while calling ProductionComponentMonitor.producerMonitorFor on monitor "
+            + monitor
+            + " with token "
+            + token,
+        e);
+  }
+
+  private static void logProducerMonitorMethodException(
+      RuntimeException e, ProducerMonitor monitor, String method) {
+    logger.log(
+        Level.SEVERE,
+        "RuntimeException while calling ProducerMonitor." + method + " on monitor " + monitor,
+        e);
+  }
+
+  private static void logProducerMonitorArgMethodException(
+      RuntimeException e, ProducerMonitor monitor, String method, Object arg) {
+    logger.log(
+        Level.SEVERE,
+        "RuntimeException while calling ProducerMonitor."
+            + method
+            + " on monitor "
+            + monitor
+            + " with "
+            + arg,
+        e);
+  }
+
+  private Monitors() {}
+}
diff --git a/producers/src/main/java/dagger/producers/monitoring/package-info.java b/producers/src/main/java/dagger/producers/monitoring/package-info.java
new file mode 100644
index 0000000..d104087
--- /dev/null
+++ b/producers/src/main/java/dagger/producers/monitoring/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.
+ */
+
+/**
+ * This package provides hooks for monitoring producers.
+ *
+ * <p>The interfaces in this package are not stable. Do not use these interfaces unless you are
+ * prepared to be broken.
+ */
+package dagger.producers.monitoring;
diff --git a/producers/src/test/java/dagger/producers/ProducedTest.java b/producers/src/test/java/dagger/producers/ProducedTest.java
new file mode 100644
index 0000000..165e730
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/ProducedTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers;
+
+import com.google.common.testing.EqualsTester;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests {@link Produced}.
+ */
+@RunWith(JUnit4.class)
+public class ProducedTest {
+  @Test public void successfulProduced() throws ExecutionException {
+    Object o = new Object();
+    assertThat(Produced.successful(5).get()).isEqualTo(5);
+    assertThat(Produced.successful("monkey").get()).isEqualTo("monkey");
+    assertThat(Produced.successful(o).get()).isSameAs(o);
+  }
+
+  @Test public void failedProduced() {
+    RuntimeException cause = new RuntimeException("monkey");
+    try {
+      Produced.failed(cause).get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isSameAs(cause);
+    }
+  }
+
+  @Test public void producedEquivalence() {
+    RuntimeException e1 = new RuntimeException("monkey");
+    RuntimeException e2 = new CancellationException();
+    new EqualsTester()
+        .addEqualityGroup(Produced.successful(132435), Produced.successful(132435))
+        .addEqualityGroup(Produced.successful("hi"), Produced.successful("hi"))
+        .addEqualityGroup(Produced.failed(e1), Produced.failed(e1))
+        .addEqualityGroup(Produced.failed(e2), Produced.failed(e2))
+        .testEquals();
+  }
+}
diff --git a/producers/src/test/java/dagger/producers/internal/AbstractProducerTest.java b/producers/src/test/java/dagger/producers/internal/AbstractProducerTest.java
new file mode 100644
index 0000000..923ea70
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/internal/AbstractProducerTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import dagger.producers.Producer;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import java.util.concurrent.ExecutionException;
+import javax.inject.Provider;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests {@link AbstractProducer}.
+ */
+@RunWith(JUnit4.class)
+public class AbstractProducerTest {
+  @Mock private ProductionComponentMonitor componentMonitor;
+  private ProducerMonitor monitor;
+  private Provider<ProductionComponentMonitor> componentMonitorProvider;
+
+  @Before
+  public void initMocks() {
+    MockitoAnnotations.initMocks(this);
+    monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS);
+    when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor);
+    componentMonitorProvider =
+        new Provider<ProductionComponentMonitor>() {
+          @Override
+          public ProductionComponentMonitor get() {
+            return componentMonitor;
+          }
+        };
+  }
+
+  @Test
+  public void get_nullPointerException() {
+    Producer<Object> producer = new DelegateProducer<>(componentMonitorProvider, null);
+    try {
+      producer.get();
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void get() throws Exception {
+    Producer<Integer> producer =
+        new AbstractProducer<Integer>(componentMonitorProvider, null) {
+          int i = 0;
+
+          @Override
+          public ListenableFuture<Integer> compute(ProducerMonitor unusedMonitor) {
+            return Futures.immediateFuture(i++);
+          }
+        };
+    assertThat(producer.get().get()).isEqualTo(0);
+    assertThat(producer.get().get()).isEqualTo(0);
+    assertThat(producer.get().get()).isEqualTo(0);
+  }
+
+  @Test
+  public void monitor_success() throws Exception {
+    SettableFuture<Integer> delegateFuture = SettableFuture.create();
+    Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture);
+
+    ListenableFuture<Integer> future = producer.get();
+    assertThat(future.isDone()).isFalse();
+    verify(monitor).addCallbackTo(any(ListenableFuture.class));
+    delegateFuture.set(-42);
+    assertThat(future.get()).isEqualTo(-42);
+    verify(monitor).succeeded(-42);
+    verifyNoMoreInteractions(monitor);
+  }
+
+  @Test
+  public void monitor_failure() throws Exception {
+    SettableFuture<Integer> delegateFuture = SettableFuture.create();
+    Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture);
+
+    ListenableFuture<Integer> future = producer.get();
+    assertThat(future.isDone()).isFalse();
+    verify(monitor).addCallbackTo(any(ListenableFuture.class));
+    Throwable t = new RuntimeException("monkey");
+    delegateFuture.setException(t);
+    try {
+      future.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isSameAs(t);
+    }
+    verify(monitor).failed(t);
+    verifyNoMoreInteractions(monitor);
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void monitor_null() throws Exception {
+    new DelegateProducer<>(null, Futures.immediateFuture(42));
+  }
+
+  static final class DelegateProducer<T> extends AbstractProducer<T> {
+    private final ListenableFuture<T> delegate;
+
+    DelegateProducer(
+        Provider<ProductionComponentMonitor> componentMonitorProvider,
+        ListenableFuture<T> delegate) {
+      super(componentMonitorProvider, null);
+      this.delegate = delegate;
+    }
+
+    @Override
+    public ListenableFuture<T> compute(ProducerMonitor unusedMonitor) {
+      return delegate;
+    }
+  }
+}
diff --git a/producers/src/test/java/dagger/producers/internal/ProducersTest.java b/producers/src/test/java/dagger/producers/internal/ProducersTest.java
new file mode 100644
index 0000000..e2707b3
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/internal/ProducersTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import javax.inject.Provider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests {@link Producers}.
+ */
+@RunWith(JUnit4.class)
+public class ProducersTest {
+  @Test public void createFutureProduced_success() throws Exception {
+    ListenableFuture<String> future = Futures.immediateFuture("monkey");
+    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
+    assertThat(producedFuture.isDone()).isTrue();
+    assertThat(producedFuture.get().get()).isEqualTo("monkey");
+  }
+
+  @Test public void createFutureProduced_failure() throws Exception {
+    ListenableFuture<String> future = Futures.immediateFailedFuture(new RuntimeException("monkey"));
+    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
+    assertThat(producedFuture.isDone()).isTrue();
+    assertThat(getProducedException(producedFuture.get()).getCause()).hasMessage("monkey");
+  }
+
+  @Test public void createFutureProduced_cancelPropagatesBackwards() throws Exception {
+    ListenableFuture<String> future = SettableFuture.create();
+    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
+    assertThat(producedFuture.isDone()).isFalse();
+    producedFuture.cancel(false);
+    assertThat(future.isCancelled()).isTrue();
+  }
+
+  @Test public void createFutureProduced_cancelDoesNotPropagateForwards() throws Exception {
+    ListenableFuture<String> future = SettableFuture.create();
+    ListenableFuture<Produced<String>> producedFuture = Producers.createFutureProduced(future);
+    assertThat(producedFuture.isDone()).isFalse();
+    future.cancel(false);
+    assertThat(producedFuture.isCancelled()).isFalse();
+    assertThat(getProducedException(producedFuture.get()).getCause())
+        .isInstanceOf(CancellationException.class);
+  }
+
+  private <T> ExecutionException getProducedException(Produced<T> produced) {
+    try {
+      produced.get();
+      throw new IllegalArgumentException("produced did not throw");
+    } catch (ExecutionException e) {
+      return e;
+    }
+  }
+
+  @Test public void createFutureSingletonSet_success() throws Exception {
+    ListenableFuture<String> future = Futures.immediateFuture("monkey");
+    ListenableFuture<Set<String>> setFuture = Producers.createFutureSingletonSet(future);
+    assertThat(setFuture.isDone()).isTrue();
+    assertThat(setFuture.get()).containsExactly("monkey");
+  }
+
+  @Test public void createFutureSingletonSet_failure() throws Exception {
+    ListenableFuture<String> future = Futures.immediateFailedFuture(new RuntimeException("monkey"));
+    ListenableFuture<Set<String>> setFuture = Producers.createFutureSingletonSet(future);
+    assertThat(setFuture.isDone()).isTrue();
+    try {
+      setFuture.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).hasMessage("monkey");
+    }
+  }
+
+  @Test public void producerFromProvider() throws Exception {
+    Producer<Integer> producer = Producers.producerFromProvider(new Provider<Integer>() {
+      int i = 0;
+
+      @Override public Integer get() {
+        return i++;
+      }
+    });
+    assertThat(producer.get().get()).isEqualTo(0);
+    assertThat(producer.get().get()).isEqualTo(0);
+    assertThat(producer.get().get()).isEqualTo(0);
+  }
+}
diff --git a/producers/src/test/java/dagger/producers/internal/SetOfProducedProducerTest.java b/producers/src/test/java/dagger/producers/internal/SetOfProducedProducerTest.java
new file mode 100644
index 0000000..e36ba05
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/internal/SetOfProducedProducerTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import dagger.producers.Produced;
+import dagger.producers.Producer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+
+/**
+ * Tests {@link SetOfProducedProducer}.
+ */
+@RunWith(JUnit4.class)
+public class SetOfProducedProducerTest {
+  @Test
+  public void success() throws Exception {
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)),
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(5, 7)));
+    assertThat(producer.get().get())
+        .containsExactly(
+            Produced.successful(1),
+            Produced.successful(2),
+            Produced.successful(5),
+            Produced.successful(7));
+  }
+
+  @Test
+  public void failure() throws Exception {
+    RuntimeException e = new RuntimeException("monkey");
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)),
+            Producers.<Set<Integer>>immediateFailedProducer(e));
+    assertThat(producer.get().get())
+        .containsExactly(
+            Produced.successful(1), Produced.successful(2), Produced.<Integer>failed(e));
+  }
+
+  @Test
+  public void delegateSetNpe() throws Exception {
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(Producers.<Set<Integer>>immediateProducer(null));
+    Results<Integer> results = Results.create(producer.get().get());
+    assertThat(results.successes).isEmpty();
+    assertThat(results.failures).hasSize(1);
+    assertThat(Iterables.getOnlyElement(results.failures).getCause())
+        .isInstanceOf(NullPointerException.class);
+  }
+
+  @Test
+  public void oneOfDelegateSetNpe() throws Exception {
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(
+            Producers.<Set<Integer>>immediateProducer(null),
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(7, 3)));
+    Results<Integer> results = Results.create(producer.get().get());
+    assertThat(results.successes).containsExactly(3, 7);
+    assertThat(results.failures).hasSize(1);
+    assertThat(Iterables.getOnlyElement(results.failures).getCause())
+        .isInstanceOf(NullPointerException.class);
+  }
+
+  @Test
+  public void delegateElementNpe() throws Exception {
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(
+            Producers.<Set<Integer>>immediateProducer(Collections.<Integer>singleton(null)));
+    Results<Integer> results = Results.create(producer.get().get());
+    assertThat(results.successes).isEmpty();
+    assertThat(results.failures).hasSize(1);
+    assertThat(Iterables.getOnlyElement(results.failures).getCause())
+        .isInstanceOf(NullPointerException.class);
+  }
+
+  @Test
+  public void oneOfDelegateElementNpe() throws Exception {
+    Producer<Set<Produced<Integer>>> producer =
+        SetOfProducedProducer.create(
+            Producers.<Set<Integer>>immediateProducer(Sets.newHashSet(Arrays.asList(5, 2, null))));
+    Results<Integer> results = Results.create(producer.get().get());
+    assertThat(results.successes).containsExactly(2, 5);
+    assertThat(results.failures).hasSize(1);
+    assertThat(Iterables.getOnlyElement(results.failures).getCause())
+        .isInstanceOf(NullPointerException.class);
+  }
+
+  static final class Results<T> {
+    final ImmutableSet<T> successes;
+    final ImmutableSet<ExecutionException> failures;
+
+    private Results(ImmutableSet<T> successes, ImmutableSet<ExecutionException> failures) {
+      this.successes = successes;
+      this.failures = failures;
+    }
+
+    static <T> Results<T> create(Set<Produced<T>> setOfProduced) {
+      ImmutableSet.Builder<T> successes = ImmutableSet.builder();
+      ImmutableSet.Builder<ExecutionException> failures = ImmutableSet.builder();
+      for (Produced<T> produced : setOfProduced) {
+        try {
+          successes.add(produced.get());
+        } catch (ExecutionException e) {
+          failures.add(e);
+        }
+      }
+      return new Results<T>(successes.build(), failures.build());
+    }
+  }
+}
diff --git a/producers/src/test/java/dagger/producers/internal/SetProducerTest.java b/producers/src/test/java/dagger/producers/internal/SetProducerTest.java
new file mode 100644
index 0000000..a38830f
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/internal/SetProducerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * 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.producers.internal;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.ListenableFuture;
+import dagger.producers.Producer;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests {@link SetProducer}.
+ */
+@RunWith(JUnit4.class)
+public class SetProducerTest {
+  @Test public void success() throws Exception {
+    Producer<Set<Integer>> producer =
+        SetProducer.create(
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)),
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(5, 7)));
+    assertThat(producer.get().get()).containsExactly(1, 2, 5, 7);
+  }
+
+  @Test public void delegateSetNpe() throws Exception {
+    Producer<Set<Integer>> producer =
+        SetProducer.create(
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)),
+            Producers.<Set<Integer>>immediateProducer(null));
+    ListenableFuture<Set<Integer>> future = producer.get();
+    try {
+      future.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
+    }
+  }
+
+  @Test public void delegateElementNpe() throws Exception {
+    Producer<Set<Integer>> producer =
+        SetProducer.create(
+            Producers.<Set<Integer>>immediateProducer(ImmutableSet.of(1, 2)),
+            Producers.<Set<Integer>>immediateProducer(Collections.<Integer>singleton(null)));
+    ListenableFuture<Set<Integer>> future = producer.get();
+    try {
+      future.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e.getCause()).isInstanceOf(NullPointerException.class);
+    }
+  }
+}
diff --git a/producers/src/test/java/dagger/producers/monitoring/internal/MonitorsTest.java b/producers/src/test/java/dagger/producers/monitoring/internal/MonitorsTest.java
new file mode 100644
index 0000000..e7f4274
--- /dev/null
+++ b/producers/src/test/java/dagger/producers/monitoring/internal/MonitorsTest.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.producers.monitoring.internal;
+
+import com.google.common.collect.ImmutableList;
+import dagger.producers.monitoring.ProducerMonitor;
+import dagger.producers.monitoring.ProducerToken;
+import dagger.producers.monitoring.ProductionComponentMonitor;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(JUnit4.class)
+public final class MonitorsTest {
+  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactory;
+  @Mock private ProductionComponentMonitor mockProductionComponentMonitor;
+  @Mock private ProducerMonitor mockProducerMonitor;
+  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryA;
+  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryB;
+  @Mock private ProductionComponentMonitor.Factory mockProductionComponentMonitorFactoryC;
+  @Mock private ProductionComponentMonitor mockProductionComponentMonitorA;
+  @Mock private ProductionComponentMonitor mockProductionComponentMonitorB;
+  @Mock private ProductionComponentMonitor mockProductionComponentMonitorC;
+  @Mock private ProducerMonitor mockProducerMonitorA;
+  @Mock private ProducerMonitor mockProducerMonitorB;
+  @Mock private ProducerMonitor mockProducerMonitorC;
+
+  @Before
+  public void initMocks() {
+    MockitoAnnotations.initMocks(this);
+  }
+
+  @Test
+  public void zeroMonitorsReturnsNoOp() {
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.<ProductionComponentMonitor.Factory>of());
+    assertThat(factory).isSameAs(Monitors.noOpProductionComponentMonitorFactory());
+  }
+
+  @Test
+  public void singleMonitor_nullProductionComponentMonitor() {
+    when(mockProductionComponentMonitorFactory.create(any(Object.class))).thenReturn(null);
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    assertThat(factory.create(new Object())).isSameAs(Monitors.noOpProductionComponentMonitor());
+  }
+
+  @Test
+  public void singleMonitor_throwingProductionComponentMonitorFactory() {
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactory)
+        .create(any(Object.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    assertThat(factory.create(new Object())).isSameAs(Monitors.noOpProductionComponentMonitor());
+  }
+
+  @Test
+  public void singleMonitor_nullProducerMonitor() {
+    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitor);
+    when(mockProductionComponentMonitor.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(null);
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    assertThat(monitor.producerMonitorFor(ProducerToken.create(Object.class)))
+        .isSameAs(Monitors.noOpProducerMonitor());
+  }
+
+  @Test
+  public void singleMonitor_throwingProductionComponentMonitor() {
+    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitor);
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitor)
+        .producerMonitorFor(any(ProducerToken.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    assertThat(monitor.producerMonitorFor(ProducerToken.create(Object.class)))
+        .isSameAs(Monitors.noOpProducerMonitor());
+  }
+
+  @Test
+  public void singleMonitor_normalProducerMonitorSuccess() {
+    setUpNormalSingleMonitor();
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitor);
+    order.verify(mockProducerMonitor).methodStarting();
+    order.verify(mockProducerMonitor).methodFinished();
+    order.verify(mockProducerMonitor).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitor);
+  }
+
+  @Test
+  public void singleMonitor_normalProducerMonitorFailure() {
+    setUpNormalSingleMonitor();
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+    Throwable t = new RuntimeException("monkey");
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.failed(t);
+
+    InOrder order = inOrder(mockProducerMonitor);
+    order.verify(mockProducerMonitor).methodStarting();
+    order.verify(mockProducerMonitor).methodFinished();
+    order.verify(mockProducerMonitor).failed(t);
+    verifyNoMoreInteractions(mockProducerMonitor);
+  }
+
+  @Test
+  public void singleMonitor_throwingProducerMonitorSuccess() {
+    setUpNormalSingleMonitor();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).succeeded(any(Object.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitor);
+    order.verify(mockProducerMonitor).methodStarting();
+    order.verify(mockProducerMonitor).methodFinished();
+    order.verify(mockProducerMonitor).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitor);
+  }
+
+  @Test
+  public void singleMonitor_throwingProducerMonitorFailure() {
+    setUpNormalSingleMonitor();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).failed(any(Throwable.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(mockProductionComponentMonitorFactory));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+    Throwable t = new RuntimeException("gorilla");
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.failed(t);
+
+    InOrder order = inOrder(mockProducerMonitor);
+    order.verify(mockProducerMonitor).methodStarting();
+    order.verify(mockProducerMonitor).methodFinished();
+    order.verify(mockProducerMonitor).failed(t);
+    verifyNoMoreInteractions(mockProducerMonitor);
+  }
+
+  @Test
+  public void multipleMonitors_nullProductionComponentMonitors() {
+    when(mockProductionComponentMonitorFactoryA.create(any(Object.class))).thenReturn(null);
+    when(mockProductionComponentMonitorFactoryB.create(any(Object.class))).thenReturn(null);
+    when(mockProductionComponentMonitorFactoryC.create(any(Object.class))).thenReturn(null);
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    assertThat(factory.create(new Object())).isSameAs(Monitors.noOpProductionComponentMonitor());
+  }
+
+  @Test
+  public void multipleMonitors_throwingProductionComponentMonitorFactories() {
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactoryA)
+        .create(any(Object.class));
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactoryB)
+        .create(any(Object.class));
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactoryC)
+        .create(any(Object.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    assertThat(factory.create(new Object())).isSameAs(Monitors.noOpProductionComponentMonitor());
+  }
+
+  @Test
+  public void multipleMonitors_someNullProductionComponentMonitors() {
+    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitorA);
+    when(mockProductionComponentMonitorFactoryB.create(any(Object.class))).thenReturn(null);
+    when(mockProductionComponentMonitorFactoryC.create(any(Object.class))).thenReturn(null);
+    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitorA);
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitorA);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorA).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitorA);
+  }
+
+  @Test
+  public void multipleMonitors_someThrowingProductionComponentMonitorFactories() {
+    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitorA);
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactoryB)
+        .create(any(Object.class));
+    doThrow(new RuntimeException("monkey"))
+        .when(mockProductionComponentMonitorFactoryC)
+        .create(any(Object.class));
+    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitorA);
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitorA);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorA).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitorA);
+  }
+
+  @Test
+  public void multipleMonitors_normalProductionComponentMonitorSuccess() {
+    setUpNormalMultipleMonitors();
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorB).methodStarting();
+    order.verify(mockProducerMonitorC).methodStarting();
+    order.verify(mockProducerMonitorC).methodFinished();
+    order.verify(mockProducerMonitorB).methodFinished();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorC).succeeded(o);
+    order.verify(mockProducerMonitorB).succeeded(o);
+    order.verify(mockProducerMonitorA).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+  }
+
+  @Test
+  public void multipleMonitors_normalProductionComponentMonitorFailure() {
+    setUpNormalMultipleMonitors();
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Throwable t = new RuntimeException("chimpanzee");
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.failed(t);
+
+    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorB).methodStarting();
+    order.verify(mockProducerMonitorC).methodStarting();
+    order.verify(mockProducerMonitorC).methodFinished();
+    order.verify(mockProducerMonitorB).methodFinished();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorC).failed(t);
+    order.verify(mockProducerMonitorB).failed(t);
+    order.verify(mockProducerMonitorA).failed(t);
+    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+  }
+
+  @Test
+  public void multipleMonitors_someThrowingProducerMonitorsSuccess() {
+    setUpNormalMultipleMonitors();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorC).succeeded(any(Object.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Object o = new Object();
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.succeeded(o);
+
+    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorB).methodStarting();
+    order.verify(mockProducerMonitorC).methodStarting();
+    order.verify(mockProducerMonitorC).methodFinished();
+    order.verify(mockProducerMonitorB).methodFinished();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorC).succeeded(o);
+    order.verify(mockProducerMonitorB).succeeded(o);
+    order.verify(mockProducerMonitorA).succeeded(o);
+    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+  }
+
+  @Test
+  public void multipleMonitors_someThrowingProducerMonitorsFailure() {
+    setUpNormalMultipleMonitors();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished();
+    doThrow(new RuntimeException("monkey")).when(mockProducerMonitorC).failed(any(Throwable.class));
+    ProductionComponentMonitor.Factory factory =
+        Monitors.delegatingProductionComponentMonitorFactory(
+            ImmutableList.of(
+                mockProductionComponentMonitorFactoryA,
+                mockProductionComponentMonitorFactoryB,
+                mockProductionComponentMonitorFactoryC));
+    ProductionComponentMonitor monitor = factory.create(new Object());
+    ProducerMonitor producerMonitor =
+        monitor.producerMonitorFor(ProducerToken.create(Object.class));
+
+    Throwable t = new RuntimeException("chimpanzee");
+    producerMonitor.methodStarting();
+    producerMonitor.methodFinished();
+    producerMonitor.failed(t);
+
+    InOrder order = inOrder(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+    order.verify(mockProducerMonitorA).methodStarting();
+    order.verify(mockProducerMonitorB).methodStarting();
+    order.verify(mockProducerMonitorC).methodStarting();
+    order.verify(mockProducerMonitorC).methodFinished();
+    order.verify(mockProducerMonitorB).methodFinished();
+    order.verify(mockProducerMonitorA).methodFinished();
+    order.verify(mockProducerMonitorC).failed(t);
+    order.verify(mockProducerMonitorB).failed(t);
+    order.verify(mockProducerMonitorA).failed(t);
+    verifyNoMoreInteractions(mockProducerMonitorA, mockProducerMonitorB, mockProducerMonitorC);
+  }
+
+  private void setUpNormalSingleMonitor() {
+    when(mockProductionComponentMonitorFactory.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitor);
+    when(mockProductionComponentMonitor.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitor);
+  }
+
+  private void setUpNormalMultipleMonitors() {
+    when(mockProductionComponentMonitorFactoryA.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitorA);
+    when(mockProductionComponentMonitorFactoryB.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitorB);
+    when(mockProductionComponentMonitorFactoryC.create(any(Object.class)))
+        .thenReturn(mockProductionComponentMonitorC);
+    when(mockProductionComponentMonitorA.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitorA);
+    when(mockProductionComponentMonitorB.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitorB);
+    when(mockProductionComponentMonitorC.producerMonitorFor(any(ProducerToken.class)))
+        .thenReturn(mockProducerMonitorC);
+  }
+}
diff --git a/test_defs.bzl b/test_defs.bzl
deleted file mode 100644
index 15ab299..0000000
--- a/test_defs.bzl
+++ /dev/null
@@ -1,195 +0,0 @@
-# Copyright (C) 2017 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.
-
-
-# Defines a set of build variants and the list of extra javacopts to build with.
-# The key will be appended to the generated test names to ensure uniqueness.
-BUILD_VARIANTS = {
-    "FastInit": ["-Adagger.fastInit=enabled"],
-    "AheadOfTimeSubcomponents": ["-Adagger.experimentalAheadOfTimeSubcomponents=enabled"],
-    "FastInitAndAheadOfTimeSubcomponents": [
-        "-Adagger.fastInit=enabled",
-        "-Adagger.experimentalAheadOfTimeSubcomponents=enabled",
-    ],
-    "AheadOfTimeSubcomponents_ForceUseSerializedComponentImplementations": [
-        "-Adagger.experimentalAheadOfTimeSubcomponents=enabled",
-        "-Adagger.forceUseSerializedComponentImplementations=enabled",
-    ],
-}
-
-# TODO(ronshapiro): convert this to use bazel_common
-# TODO(user): split into two functions for functional vs non-functional tests?
-def GenJavaTests(
-        name,
-        srcs,
-        deps,
-        test_only_deps = None,
-        plugins = None,
-        javacopts = None,
-        lib_javacopts = None,
-        test_javacopts = None,
-        functional = True):
-    _GenTests(
-        native.java_library,
-        native.java_test,
-        name,
-        srcs,
-        deps,
-        test_only_deps,
-        plugins,
-        javacopts,
-        lib_javacopts,
-        test_javacopts,
-        functional,
-    )
-
-def GenRobolectricTests(
-        name,
-        srcs,
-        deps,
-        test_only_deps = None,
-        plugins = None,
-        javacopts = None,
-        lib_javacopts = None,
-        test_javacopts = None,
-        functional = True,
-        manifest_values = None):
-    # TODO(ronshapiro): enable these with these instructions:
-    # https://docs.bazel.build/versions/master/be/android.html#android_local_test_examples
-    # We probably want to import all of Robolectric's dependencies into bazel-common because there
-    # are some differences (i.e. we both provide Guava).
-    pass
-
-def _GenTests(
-        library_rule_type,
-        test_rule_type,
-        name,
-        srcs,
-        deps,
-        test_only_deps = None,
-        plugins = None,
-        javacopts = None,
-        lib_javacopts = None,
-        test_javacopts = None,
-        functional = True,
-        test_kwargs = {}):
-    _gen_tests(
-        library_rule_type,
-        test_rule_type,
-        name,
-        srcs,
-        deps,
-        test_only_deps,
-        plugins,
-        javacopts,
-        lib_javacopts,
-        test_javacopts,
-        functional,
-        test_kwargs = test_kwargs,
-    )
-
-    if functional:
-        for (variant_name, extra_javacopts) in BUILD_VARIANTS.items():
-            variant_javacopts = (javacopts or []) + extra_javacopts
-            _gen_tests(
-                library_rule_type,
-                test_rule_type,
-                name,
-                srcs,
-                deps,
-                test_only_deps,
-                plugins,
-                variant_javacopts,
-                lib_javacopts,
-                test_javacopts,
-                functional,
-                variant_name,
-                test_kwargs = test_kwargs,
-            )
-
-def _gen_tests(
-        library_rule_type,
-        test_rule_type,
-        name,
-        srcs,
-        deps,
-        test_only_deps,
-        plugins,
-        javacopts,
-        lib_javacopts,
-        test_javacopts,
-        functional,
-        variant_name = None,
-        test_kwargs = {}):
-    if variant_name:
-        suffix = "_" + variant_name
-        tags = [variant_name]
-
-        # Add jvm_flags so that the mode can be accessed from within tests.
-        jvm_flags = ["-Ddagger.mode=" + variant_name]
-    else:
-        suffix = ""
-        tags = []
-        jvm_flags = []
-
-    test_files = []
-    supporting_files = []
-
-    for src in srcs:
-        if src.endswith("Test.java"):
-            test_files.append(src)
-        else:
-            supporting_files.append(src)
-
-    if not test_only_deps:
-        test_only_deps = []
-
-    test_deps = test_only_deps + deps
-    if supporting_files:
-        supporting_files_name = name + suffix + "_lib"
-        test_deps.append(":" + supporting_files_name)
-        library_rule_type(
-            name = supporting_files_name,
-            testonly = 1,
-            srcs = supporting_files,
-            javacopts = (javacopts or []) + (lib_javacopts or []),
-            plugins = plugins,
-            tags = tags,
-            deps = deps,
-        )
-        if functional:
-            _hjar_test(supporting_files_name, tags)
-
-    for test_file in test_files:
-        test_name = test_file.replace(".java", "")
-        prefix_path = "src/test/java/"
-        package_name = native.package_name()
-        if package_name.find("javatests/") != -1:
-            prefix_path = "javatests/"
-        test_class = (package_name + "/" + test_name).rpartition(prefix_path)[2].replace("/", ".")
-        test_rule_type(
-            name = test_name + suffix,
-            srcs = [test_file],
-            javacopts = (javacopts or []) + (test_javacopts or []),
-            jvm_flags = jvm_flags,
-            plugins = plugins,
-            tags = tags,
-            test_class = test_class,
-            deps = test_deps,
-            **test_kwargs
-        )
-
-
-def _hjar_test(name, tags):
-    pass
diff --git a/tools/BUILD b/tools/BUILD
deleted file mode 100644
index 7b3cc6c..0000000
--- a/tools/BUILD
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Description:
-#   Tools for Dagger
-
-package(default_visibility = ["//:src"])
-
-exports_files([
-    "pom-template.xml",
-])
diff --git a/tools/maven.bzl b/tools/maven.bzl
deleted file mode 100644
index 2ac0359..0000000
--- a/tools/maven.bzl
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018 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.
-
-"""Macros to simplify generating maven files.
-"""
-
-load("@google_bazel_common//tools/maven:pom_file.bzl", default_pom_file = "pom_file")
-
-def pom_file(name, targets, artifact_name, artifact_id, packaging = None, **kwargs):
-    default_pom_file(
-        name = name,
-        targets = targets,
-        preferred_group_ids = [
-            "com.google.dagger",
-            "com.google",
-        ],
-        template_file = "//tools:pom-template.xml",
-        substitutions = {
-            "{artifact_name}": artifact_name,
-            "{artifact_id}": artifact_id,
-            "{packaging}": packaging or "jar",
-        },
-        excluded_artifacts = ["com.google.auto:auto-common"],
-        **kwargs
-    )
-
-POM_VERSION = "2.23.1"
diff --git a/tools/pom-template.xml b/tools/pom-template.xml
deleted file mode 100644
index 39ed62d..0000000
--- a/tools/pom-template.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.sonatype.oss</groupId>
-    <artifactId>oss-parent</artifactId>
-    <version>7</version>
-  </parent>
-
-  <groupId>com.google.dagger</groupId>
-  <artifactId>{artifact_id}</artifactId>
-  <name>{artifact_name}</name>
-  <version>{pom_version}</version>
-  <description>A fast dependency injector for Android and Java.</description>
-  <url>https://github.com/google/dagger</url>
-  <packaging>{packaging}</packaging>
-
-  <scm>
-    <url>http://github.com/google/dagger/</url>
-    <connection>scm:git:git://github.com/google/dagger.git</connection>
-    <developerConnection>scm:git:ssh://git@github.com/google/dagger.git</developerConnection>
-    <tag>HEAD</tag>
-  </scm>
-
-  <issueManagement>
-    <system>GitHub Issues</system>
-    <url>http://github.com/google/dagger/issues</url>
-  </issueManagement>
-
-  <licenses>
-    <license>
-      <name>Apache 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-    </license>
-  </licenses>
-
-  <organization>
-    <name>Google, Inc.</name>
-    <url>http://www.google.com</url>
-  </organization>
-
-  <dependencies>
-{generated_bzl_deps}
-  </dependencies>
-</project>
diff --git a/util/deploy-to-maven-central.sh b/util/deploy-to-maven-central.sh
deleted file mode 100755
index 1f721a1..0000000
--- a/util/deploy-to-maven-central.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-
-set -eu
-
-if [ $# -lt 2 ]; then
-  echo "usage $0 <ssl-key> <version-name> [<param> ...]"
-  exit 1;
-fi
-key=$1
-version_name=$2
-shift 2
-
-if [[ ! "$version_name" =~ ^2\. ]]; then
-  echo 'Version name must begin with "2."'
-  exit 2
-fi
-
-if [[ "$version_name" =~ " " ]]; then
-  echo "Version name must not have any spaces"
-  exit 3
-fi
-
-bazel test //...
-
-bash $(dirname $0)/execute-deploy.sh \
-  "gpg:sign-and-deploy-file" \
-  "$version_name" \
-  "-DrepositoryId=sonatype-nexus-staging" \
-  "-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/" \
-  "-Dgpg.keyname=${key}"
-
-# Publish javadocs to gh-pages
-bazel build //:user-docs.jar
-git clone --quiet --branch gh-pages \
-    https://github.com/google/dagger gh-pages > /dev/null
-cd gh-pages
-unzip ../bazel-bin/user-docs.jar -d api/$version_name
-rm -rf api/$version_name/META-INF/
-git add api/$version_name
-git commit -m "$version_name docs"
-git push origin gh-pages
-cd ..
-rm -rf gh-pages
-
-git checkout --detach
-# Set the version string that is used as a tag in all of our libraries. If another repo depends on
-# a versioned tag of Dagger, their java_library.tags should match the versioned release.
-sed -i s/'${project.version}'/"${version_name}"/g tools/maven.bzl
-git commit -m "${version_name} release" tools/maven.bzl
-
-git tag -a -m "Dagger ${version_name}" dagger-"${version_name}"
-git push origin tag dagger-"${version_name}"
-
-# Switch back to the original HEAD
-git checkout -
diff --git a/util/execute-deploy.sh b/util/execute-deploy.sh
deleted file mode 100755
index 1153468..0000000
--- a/util/execute-deploy.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/bash
-
-set -eu
-
-readonly MVN_GOAL="$1"
-readonly VERSION_NAME="$2"
-shift 2
-readonly EXTRA_MAVEN_ARGS=("$@")
-
-bazel_output_file() {
-  local library=$1
-  local output_file=bazel-bin/$library
-  if [[ ! -e $output_file ]]; then
-     output_file=bazel-genfiles/$library
-  fi
-  if [[ ! -e $output_file ]]; then
-    echo "Could not find bazel output file for $library"
-    exit 1
-  fi
-  echo -n $output_file
-}
-
-deploy_library() {
-  local library=$1
-  local srcjar=$2
-  local javadoc=$3
-  local pomfile=$4
-  bazel build --define=pom_version="$VERSION_NAME" \
-    $library $srcjar $javadoc $pomfile
-
-  mvn $MVN_GOAL \
-    -Dfile=$(bazel_output_file $library) \
-    -Djavadoc=$(bazel_output_file $javadoc) \
-    -DpomFile=$(bazel_output_file $pomfile) \
-    -Dsources=$(bazel_output_file $srcjar) \
-    "${EXTRA_MAVEN_ARGS[@]:+${EXTRA_MAVEN_ARGS[@]}}"
-}
-
-deploy_library \
-  java/dagger/libcore.jar \
-  java/dagger/libcore-src.jar \
-  java/dagger/core-javadoc.jar \
-  java/dagger/pom.xml
-
-deploy_library \
-  gwt/libgwt.jar \
-  gwt/libgwt.jar \
-  gwt/libgwt.jar \
-  gwt/pom.xml
-
-deploy_library \
-  shaded_compiler.jar \
-  shaded_compiler_src.jar \
-  java/dagger/internal/codegen/codegen-javadoc.jar \
-  java/dagger/internal/codegen/pom.xml
-
-deploy_library \
-  java/dagger/producers/libproducers.jar \
-  java/dagger/producers/libproducers-src.jar \
-  java/dagger/producers/producers-javadoc.jar \
-  java/dagger/producers/pom.xml
-
-deploy_library \
-  shaded_spi.jar \
-  shaded_spi_src.jar \
-  spi-javadoc.jar \
-  java/dagger/spi/pom.xml
-
-deploy_library \
-  java/dagger/android/android.aar \
-  java/dagger/android/libandroid-src.jar \
-  java/dagger/android/android-javadoc.jar \
-  java/dagger/android/pom.xml
-
-# b/37741866 and https://github.com/google/dagger/issues/715
-deploy_library \
-  java/dagger/android/libandroid.jar \
-  java/dagger/android/libandroid-src.jar \
-  java/dagger/android/android-javadoc.jar \
-  java/dagger/android/jarimpl-pom.xml
-
-deploy_library \
-  java/dagger/android/support/support.aar \
-  java/dagger/android/support/libsupport-src.jar \
-  java/dagger/android/support/support-javadoc.jar \
-  java/dagger/android/support/pom.xml
-
-deploy_library \
-  shaded_android_processor.jar \
-  java/dagger/android/processor/libprocessor-src.jar \
-  java/dagger/android/processor/processor-javadoc.jar \
-  java/dagger/android/processor/pom.xml
-
-deploy_library \
-  java/dagger/grpc/server/libserver.jar \
-  java/dagger/grpc/server/libserver-src.jar \
-  java/dagger/grpc/server/javadoc.jar \
-  java/dagger/grpc/server/server-pom.xml
-
-deploy_library \
-  java/dagger/grpc/server/libannotations.jar \
-  java/dagger/grpc/server/libannotations-src.jar \
-  java/dagger/grpc/server/javadoc.jar \
-  java/dagger/grpc/server/annotations-pom.xml
-
-deploy_library \
-  shaded_grpc_server_processor.jar \
-  java/dagger/grpc/server/processor/libprocessor-src.jar \
-  java/dagger/grpc/server/processor/javadoc.jar \
-  java/dagger/grpc/server/processor/pom.xml
diff --git a/util/generate-latest-docs.sh b/util/generate-latest-docs.sh
index 8e9304c..b68df0c 100755
--- a/util/generate-latest-docs.sh
+++ b/util/generate-latest-docs.sh
@@ -1,30 +1,25 @@
 # see http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/ for details
 
-set -eu
-
 if [ "$TRAVIS_REPO_SLUG" == "google/dagger" ] && \
-   [ "$TRAVIS_JDK_VERSION" == "$JDK_FOR_PUBLISHING" ] && \
+   [ "$TRAVIS_JDK_VERSION" == "oraclejdk7" ] && \
    [ "$TRAVIS_PULL_REQUEST" == "false" ] && \
    [ "$TRAVIS_BRANCH" == "master" ]; then
   echo -e "Publishing javadoc...\n"
-  bazel build //:user-docs.jar
-  JAVADOC_JAR="$(pwd)/bazel-bin/user-docs.jar"
+  mvn javadoc:aggregate -P!examples
+  TARGET="$(pwd)/target"
 
   cd $HOME
   git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/google/dagger gh-pages > /dev/null
-
+  
   cd gh-pages
   git config --global user.email "travis@travis-ci.org"
   git config --global user.name "travis-ci"
-  git rm -rf api/latest
+  git rm -rf api/latest 
   mkdir -p api
-  unzip "$JAVADOC_JAR" -d api/latest
-  rm -rf api/latest/META-INF/
+  mv ${TARGET}/site/apidocs api/latest
   git add -f api/latest
-  git commit -m "Latest javadoc on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
+  git commit -m "Lastest javadoc on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
   git push -fq origin gh-pages > /dev/null
 
   echo -e "Published Javadoc to gh-pages.\n"
-else
-  echo -e "Not publishing docs for jdk=${TRAVIS_JDK_VERSION} and branch=${TRAVIS_BRANCH}"
 fi
diff --git a/util/install-local-snapshot.sh b/util/install-local-snapshot.sh
deleted file mode 100755
index 8f77a41..0000000
--- a/util/install-local-snapshot.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-set -eu
-
-echo -e "Installing maven snapshot locally...\n"
-
-bash $(dirname $0)/execute-deploy.sh \
-  "install:install-file" \
-  "LOCAL-SNAPSHOT"
-
-echo -e "Installed local snapshot"
diff --git a/util/mvn-deploy.sh b/util/mvn-deploy.sh
new file mode 100755
index 0000000..ec4b7a0
--- /dev/null
+++ b/util/mvn-deploy.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+if [ $# -lt 1 ]; then
+  echo "usage $0 <ssl-key> [<param> ...]"
+  exit 1;
+fi
+key=$1
+shift
+
+#validate key
+keystatus=$(gpg --list-keys | grep ${key} | awk '{print $1}')
+if [ "${keystatus}" != "pub" ]; then
+  echo "Could not find public key with label ${key}"
+  echo -n "Available keys from: "
+  gpg --list-keys | grep --invert-match '^sub'
+
+  exit 64
+fi
+
+mvn "$@" -P '!examples' -P sonatype-oss-release \
+    -Dgpg.skip=false -Dgpg.keyname=${key} \
+    clean site:jar deploy
diff --git a/util/publish-snapshot-on-commit.sh b/util/publish-snapshot-on-commit.sh
index 944a2c3..be27cb6 100755
--- a/util/publish-snapshot-on-commit.sh
+++ b/util/publish-snapshot-on-commit.sh
@@ -1,21 +1,12 @@
 # see https://coderwall.com/p/9b_lfq
 
-set -eu
-
 if [ "$TRAVIS_REPO_SLUG" == "google/dagger" ] && \
-   [ "$TRAVIS_JDK_VERSION" == "$JDK_FOR_PUBLISHING" ] && \
+   [ "$TRAVIS_JDK_VERSION" == "oraclejdk7" ] && \
    [ "$TRAVIS_PULL_REQUEST" == "false" ] && \
    [ "$TRAVIS_BRANCH" == "master" ]; then
   echo -e "Publishing maven snapshot...\n"
 
-  bash $(dirname $0)/execute-deploy.sh \
-    "deploy:deploy-file" \
-    "HEAD-SNAPSHOT" \
-    "-DrepositoryId=sonatype-nexus-snapshots" \
-    "-Durl=https://oss.sonatype.org/content/repositories/snapshots" \
-    "--settings=$(dirname $0)/settings.xml"
+  mvn clean source:jar deploy --settings="util/settings.xml" -DskipTests=true -Dinvoker.skip=true -Dmaven.javadoc.skip=true
 
   echo -e "Published maven snapshot"
-else
-  echo -e "Not publishing snapshot for jdk=${TRAVIS_JDK_VERSION} and branch=${TRAVIS_BRANCH}"
 fi